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 + 1.
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.
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.
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.
5 1 2 3 4 5
4 5 2 3 1
6 15 14 3 13 1 12
12 13 14 7 3 1
6 9 7 13 17 5 11
4 5 2 6 3 1
题目大意:
让你构造一个长度为N的数组X【】,使得其能够通过两种操作得到数组Y【】;
现在给你一个数组Y【】,让你构造一个可行X【】,使得其中最大值尽可能的小。
两种操作:
选择x【i】,使得其变成X【i】*2或者是X【i】*2+1.....
保证Y【】是一个不包含重复元素的数组,要求X【】也不能包含重复元素。而且所有元素大于0.
思路:
1、考虑问题本质,其实我们最开始可以设定ans【】(X【】)就是Y【】;
然后尽可能的缩小最大值,来寻找一个最终序列,使得X【】中最大元素尽可能的小。
2、那么首先我们将数组Y【】从大到小排序,然后全部塞到一个优先队列中,每次我们拿出最大值,肯定想要做到的就是将这个数变小,变成一个和此时队列中所有元素不相同的小值。
那么我们每一次取队头元素,将其尽可能的变小,如果可以变小,再将变小的值塞进队列,继续取队头,循环往复。
直到不能变小为止,停止操作即可。
Ac代码:
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<map>
#include<queue>
using namespace std;
struct node
{
int val;
friend bool operator <(node a,node b)
{
return a.val<b.val;
}
}nod;
int a[50050];
int ans[50050];
int b[500];
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)scanf("%d",&a[i]);
sort(a,a+n);reverse(a,a+n);
priority_queue<node>s;
map<int ,int >ss;
for(int i=0;i<n;i++)
{
nod.val=a[i];
ss[a[i]]=1;
s.push(nod);
}
while(1)
{
int flag=0;
nod=s.top();
while(nod.val)
{
nod.val/=2;
if(ss[nod.val]==0&&nod.val!=0)
{
flag=1;
ss[nod.val]=1;
s.pop();
s.push(nod);
break;
}
}
if(flag==0)break;
}
while(!s.empty())
{
nod=s.top();
s.pop();
printf("%d ",nod.val);
}
printf("\n");
}
}