D. Generating Sets(贪心&堆)

考虑对y数组方向操作,也就是除以2向下取整。

维护一个大顶堆,每次取最大值,然后如果除以2后没出现在堆里就继续除。

时间复杂度: O ( n l o g 2 n ) O(nlog^2n) O(nlog2n)

// Problem: D. Generating Sets
// Contest: Codeforces - Intel Code Challenge Elimination Round (Div. 1 + Div. 2, combined)
// URL: https://codeforces.ml/contest/722/problem/D
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// Date: 2021-08-03 18:47:33
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=5e4+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define IOS ios::sync_with_stdio(false),cin.tie(0) 
void Print(int *a,int n){
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\n",a[n]); 
}
int n;
set<int>s;
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		int x;scanf("%d",&x);s.insert(x);
	}
	while(true){
		int now=*s.rbegin();
		while(now&&s.count(now)) now>>=1;
		if(!now) break;
		s.erase(--s.end());
		s.insert(now);
	}
	for(int x:s) printf("%d ",x);printf("\n");
	return 0;
}