Codeforces925C Big Secret 【构造】【贪心】
题目大意:给出异或差分序列,要你任意排列使得原序列递增。
题目分析:
我们在使得异或结果递增的过程中总能找到一个值使得它的最高位的1对应当前值的0。那么我们贪心的选择最高位最低的一个任意值使得它满足这个关系。
这是因为当我们现在异或的值的最高位为k时,它前面有关的位全部都是1,而后面的位不受影响,异或上这个值只会对当前异或的数产生影响而不会对其它数产生坏的影响。也就是说异或上某一个值之后能异或的值除了自己之外只会变多或不变。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 typedef long long ll; 5 6 int n; 7 ll d[200000]; 8 9 vector <ll> bit[68]; 10 11 void read(){ 12 scanf("%d",&n); 13 for(int i=1;i<=n;i++){ 14 scanf("%lld",&d[i]); 15 for(int j=59;j>=0;j--){ 16 if((1ll<<j) & d[i]) { bit[j].push_back(d[i]);break;} 17 } 18 } 19 } 20 21 ll ans[250000]; 22 void work(){ 23 ll x = 0; 24 for(int i=1;i<=n;i++){ 25 int flag = false; 26 for(int j=0;j<60;j++){ 27 if(((1ll<<j)&x)==0 && bit[j].size()){ 28 ans[i] = bit[j][bit[j].size()-1]; 29 x ^= bit[j][bit[j].size()-1]; 30 bit[j].pop_back(); 31 flag = true; 32 break; 33 } 34 } 35 if(!flag){puts("No");return;} 36 } 37 puts("Yes"); 38 for(int i=1;i<=n;i++){ printf("%lld ",ans[i]);} 39 } 40 41 int main(){ 42 read(); 43 work(); 44 return 0; 45 }