【CodeForces - 722D】Generating Sets(二分,贪心)
題干:
You are given a set?Y?of?n?distinct?positive integers?y1,?y2,?...,?yn.
Set?X?of?n?distinct?positive integers?x1,?x2,?...,?xn?is said to?generate?set?Y?if one can transform?X?to?Y?by applying some number of the following two operation to integers in?X:
Note that integers in?X?are not required to be distinct after each operation.
Two sets of distinct integers?X?and?Y?are equal if they are equal as sets. In other words, if we write elements of the sets in the array in the increasing order, these arrays would be equal.
Note, that any set of integers (or its permutation) generates itself.
You are given a set?Y?and have to find a set?X?that generates?Y?and the?maximum element of?X?is mininum possible.
Input
The first line of the input contains a single integer?n?(1?≤?n?≤?50?000)?— the number of elements in?Y.
The second line contains?n?integers?y1,?...,?yn?(1?≤?yi?≤?109), that are guaranteed to be distinct.
Output
Print?n?integers?— set of distinct integers that generate?Y?and the maximum element of which is minimum possible. If there are several such sets, print any of them.
Examples
Input
5 1 2 3 4 5Output
4 5 2 3 1Input
6 15 14 3 13 1 12Output
12 13 14 7 3 1Input
6 9 7 13 17 5 11Output
4 5 2 6 3 1題目大意:
有一個(gè)原數(shù)列a,你可以對任何一個(gè)數(shù)字進(jìn)行操作,令x變?yōu)?*x 或2*x+1?,F(xiàn)在給你一個(gè)目標(biāo)數(shù)列b,讓你求一個(gè)原數(shù)列,原數(shù)列可能有多個(gè),要求你求的這個(gè)原數(shù)列最大的一個(gè)元素最小。注意原數(shù)列和目標(biāo)數(shù)列都必須滿足每個(gè)元素都不相同,但是在變化的過程中(也就是2*x,2*x+1這種變換過程中)不需要滿足這個(gè)條件。
輸入:第一行一個(gè)數(shù)n,第二行n個(gè)數(shù)代表b數(shù)組。
解題報(bào)告:
將數(shù)字之間的變換畫出來發(fā)現(xiàn)是一棵二叉樹,所以每個(gè)bi變小的過程,是唯一的,因?yàn)楦腹?jié)點(diǎn)是唯一的。發(fā)現(xiàn)從最小的數(shù)開始貪心或從大的數(shù)開始貪心都不是很合適,所以二分上界,然后從大到小貪心,讓大的數(shù)字找地方放下,能放下則放下,給小的數(shù)字騰出盡可能大的空間,不難證明這種貪心的正確性。代碼是勉勉強(qiáng)強(qiáng)的O(n*lognlogn)的復(fù)雜度。
當(dāng)然這題可以不用二分,直接拿個(gè)優(yōu)先隊(duì)列也可,這樣復(fù)雜度可以做到O(nlogn)。
AC代碼:
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<stack> #include<map> #include<vector> #include<unordered_set> #include<string> #include<cmath> #include<cstring> #define FF first #define SS second #define ll long long #define pb push_back #define pm make_pair using namespace std; typedef pair<int,int> PII; const int MAX = 50000 + 6; int n,a[MAX],mx; vector<int> ans,tmp; unordered_set<int> ss; bool ok(int up) {tmp.clear();ss.clear();//從大到小進(jìn)行安排位置for(int x,i = 1; i<=n; i++) {x = a[i];while(x >= 1) {if(x<=up && ss.find(x) == ss.end()) {ss.insert(x);tmp.pb(x);break;}if(x&1) x=(x-1)/2;else x=x/2;}}return (int)tmp.size() == n; } int main() { // cout << log2(50000)*log2(50000)*log2(50000)*50000<<endl;cin >> n;for(int i = 1; i<=n; i++) scanf("%d",a+i),mx=max(mx,a[i]);sort(a+1,a+n+1); reverse(a+1,a+n+1);int l = 1,r = mx,mid;while(l<=r) {mid=(l+r)>>1;if(ok(mid)) r = mid-1,ans=tmp;else l = mid+1;}for(auto x : ans) printf("%d ",x);return 0 ; }?
總結(jié)
以上是生活随笔為你收集整理的【CodeForces - 722D】Generating Sets(二分,贪心)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2017年中国银行微信申请信用卡秒批方法
- 下一篇: 银行推出特色存款,存10万一年可拿近5千