码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces925C Big Secret 【构造】【贪心】

时间:2018-05-02 16:18:04      阅读:249      评论:0      收藏:0      [点我收藏+]

标签:turn   secret   选择   scanf   排列   pop   pre   style   puts   

题目大意:给出异或差分序列,要你任意排列使得原序列递增。

 

题目分析:

我们在使得异或结果递增的过程中总能找到一个值使得它的最高位的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 }

 

Codeforces925C Big Secret 【构造】【贪心】

标签:turn   secret   选择   scanf   排列   pop   pre   style   puts   

原文地址:https://www.cnblogs.com/Menhera/p/8979745.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!