题意:

给以一个目标序列n(5e4)个数,每个数大小1e9,问你最大值最小的原序列是什么 spj

每个数可以变为*2或者*2+1,原序列和目标序列没有重复的数,变换过程中可以出现

思路:

把最大的数/2变小,直到当前序列中的最大值无法变小就得到了一个原序列了

/* ***********************************************
Author        :devil
************************************************ */
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <map>
#include <string>
#include <time.h>
#include <cmath>
#include <stdlib.h>
#define LL long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define ou(a) printf("%d\n",a)
#define pb push_back
#define mkp make_pair
template<class T>inline void rd(T &x)
{
    char c=getchar();
    x=0;
    while(!isdigit(c))c=getchar();
    while(isdigit(c))
    {
        x=x*10+c-'0';
        c=getchar();
    }
}
#define IN freopen("in.txt","r",stdin);
#define OUT freopen("out.txt","w",stdout);
using namespace std;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int N=5e4+10;
int n,x;
set<int>a;
int ok(int ma)
{
    while(ma>=1&&(*a.lower_bound(ma))==ma) ma/=2;
    return ma;
}
int main()
{
#ifndef ONLINE_JUDGE
//IN
#endif
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&x);
        a.insert(x);
    }
    while(1)
    {
        int p=*(--a.end());
        int q=ok(p/2);
        if(q)
        {
            a.erase(p);
            a.insert(q);
        }
        else break;
    }
    for(auto p=a.begin();p!=a.end();p++) printf("%d ",*p);
    return 0;
}