Big Secret
Big Secret 题解
solution
问题一,考虑已知 b 序列,如何还原出 a 序列。
显然,由于
于是我们可以通过记录
问题二,如何求最小的 b 序列。
记我们重新排序后的
题目限制了
记我们正处理的数为
1°当
2°当
3°当
于是我们开优先队列
code
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,b[100005];
int ans[100005],cnt=0;
int minn=0x3f3f3f3f3f3f3f3f,pla;
priority_queue<int,vector<int>,greater<int> >q[100005];
int bitc(int x){
int a=0;
while(x>0){
a++;
x>>=1;
}
return a-1;
}
signed main(){
scanf("%lld",&n);
for(int i=1;i<=n;++i)scanf("%lld",&b[i]);
for(int i=1;i<=n;++i)
if(b[i]<minn){
minn=b[i];
pla=i;
}
for(int i=1;i<=n;++i){
if(i==pla)continue;
q[bitc(b[i])].push(b[i]);
}
ans[++cnt]=b[pla];
int nowc=bitc(b[pla]),now=b[pla];
while(cnt<n){
int cntt=0;
while((q[cntt].empty()||now>>cntt&1)&&cntt<=nowc-1)++cntt;
if(cntt==nowc){
cntt=nowc+1;
while(cntt<64&&q[cntt].empty())++cntt;
if(cntt==64){
printf("No\n");
return 0;
}
now^=q[cntt].top();
nowc=bitc(q[cntt].top());
ans[++cnt]=q[cntt].top();
q[cntt].pop();
}
else{
now^=q[cntt].top();
ans[++cnt]=q[cntt].top();
q[cntt].pop();
}
}
printf("Yes\n");
for(int i=1;i<=cnt;++i)printf("%lld ",ans[i]);
return 0;
}