D. Generating Sets
time limit per test
memory limit per test
input
output
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:
- Take any integer xi and multiply it by two, i.e. replace xi with 2·xi.
- Take any integer xi, multiply it by two and add one, i.e. replace xi with 2·xi.
Note that integers in X
Two sets of distinct integers X and Y
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.
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
Examples
input
5
1 2 3 4 5
output
4 5 2 3 1
input
6
15 14 3 13 1 12
output
12 13 14 7 3 1
input
6
9 7 13 17 5 11
output
4 5 2 6 3 1
用二分枚举最大值d, 在遍历每一个数num[i], 判断其是否大于d, 若大于,则除二,并且利用set判重,直到除到小于d,且不重复即可
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <set>
#define maxn 100005
using namespace std;
typedef long long ll;
set<int> s;
int num[50005], n;
bool judge(int m){
for(int i = 0; i < n; i++){
if(num[i] <= n && s.count(num[i]) == 0)
s.insert(num[i]);
else{
int h = num[i];
while(h >= 1 && (h > m || s.count(h))){
h /= 2;
}
if(h == 0)
return false;
s.insert(h);
}
}
return true;
}
int main(){
// freopen("in.txt", "r", stdin);
int l = 0, r = 0;
scanf("%d", &n);
for(int i = 0; i < n; i++){
scanf("%d", num+i);
r = max(r, num[i]);
}
while(l < r){
s.clear();
int mid = (l + r) >> 1;
if(judge(mid))
r = mid;
else
l = mid + 1;
}
s.clear();
judge(l);
set<int> ::iterator iter = s.begin();
printf("%d", *iter++);
for(; iter != s.end(); iter++){
printf(" %d", *iter);
}
puts("");
return 0;
}