Codeforces Round #626 (Div. 1, based on Moscow Open Olympiad in Informatics)B(位运算,二分查找)

从低到高枚举当前位i,把所有数字对1<<(i+1)取模,因为比i位高的数字不会影响到低位,在这些数中,两两组成一对,每对的和如果在第i位上为1,++计数,如果计数为奇数,则答案上这一位为1。这个组对的过程通过排序后二分查找完成。

 

 1 #define HAVE_STRUCT_TIMESPEC
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 int a[400007];
 5 int b[400007];
 6 int main(){
 7     ios::sync_with_stdio(false);
 8     cin.tie(NULL);
 9     cout.tie(NULL);
10     int n;
11     cin>>n;
12     for(int i=1;i<=n;++i)
13         cin>>a[i];
14     int ans=0;
15     for(int i=0;i<26;++i){
16         for(int j=1;j<=n;++j)
17             b[j]=a[j]%(1<<(i+1));
18         sort(b+1,b+1+n);
19         long long sum=0;
20         for(int j=1;j<=n;++j){
21             sum+=n-(lower_bound(b+1,b+1+n,(1<<i)+(1<<(i+1))-b[j])-b-1);//两个数相加大于等于2^i+2^(i+1)
22             if(b[j]*2>=(1<<i)+(1<<(i+1)))//查找到的数中包含b[j]自己
23                 --sum;
24             sum+=upper_bound(b+1,b+1+n,(1<<(i+1))-1-b[j])-lower_bound(b+1,b+1+n,(1<<i)-b[j]);//两个数相加大于等于2^i,小于等于2^(i+1)-1
25             if(b[j]*2>=(1<<i)&&b[j]*2<=(1<<(i+1))-1)//查找到的数中包含b[j]自己
26                 --sum;
27         }
28         if((sum/2)&1)//不分前后的查找多计算了一倍
29             ans+=(1<<i);
30     }
31     cout<<ans;
32     return 0;
33 }

 

posted @ 2020-03-08 18:58  sewage  阅读(212)  评论(0编辑  收藏  举报