从低到高枚举当前位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 }