思路:

我也不知道为什么写这个代码调了一会.思路其实比较简单,就是维护一个,从大的能消则消,不能消则加入答案,这样一次一次的变小,最后集合肯定是一个最小的,因为我是从最大的开始消的.每次操作是次,维护一个,然后时间复杂度应该是具体实现过程见代码.

代码:

#include <bits/stdc++.h>
using namespace std;
unordered_map<int,bool>p;
set<int>s;
int work(int x,int root)
{
    if(x==1&&p[x])    return root;
    if(!p[x])        return x;
    if(x&1)
    {
        return work((x-1)/2,root);
    }
    else
    {
        return work(x/2,root);
    }
}

int main()
{
    int n;cin>>n;vector<int>ans;
    for(int i=1;i<=n;i++)
    {
        int x;cin>>x;
        s.insert(x);p[x]=true;    
    }
    while(s.size())
    {
        int op=*s.rbegin();
        int now=work(op,op);
        if(now==op)    ans.push_back(op),s.erase(op);
        else        s.erase(op),s.insert(now),p[now]=true;
    }
    for(int x:ans)
    {
        cout<<x<<' ';
    }puts("");
    return 0;   
}