题目
题意:
给定一个数组,求(a1+a2)^ (a1+a3) ^ (a1+a4) ^…(a2+a3) ^ (a2+a4) ^ … ^(an-1+an)。
2
≤
n
≤
400000
,
1
≤
a
i
≤
1
0
7
2≤n≤400000,1≤a_i≤10^7
2≤n≤400000,1≤ai≤107
分析:
对
于
这
种
位
运
算
,
我
们
肯
定
是
考
虑
答
案
的
二
进
制
下
每
一
位
的
数
值
。
当
我
们
考
虑
对于这种位运算,我们肯定是考虑答案的二进制下每一位的数值。当我们考虑
对于这种位运算,我们肯定是考虑答案的二进制下每一位的数值。当我们考虑
第
k
位
时
,
可
以
先
将
a
数
组
模
2
k
+
1
,
并
不
影
响
第
k
位
的
结
果
,
即
高
位
不
影
响
低
位
。
第k位时,可以先将a数组模2^{k+1},并不影响第k位的结果,即高位不影响低位。
第k位时,可以先将a数组模2k+1,并不影响第k位的结果,即高位不影响低位。
当
第
k
位
为
1
时
,
当
a
i
+
a
j
在
区
间
[
2
k
,
2
k
+
1
−
1
]
或
[
2
k
+
1
+
2
k
,
2
k
+
2
−
1
]
时
,
会
对
答
案
的
第
k
位
产
生
贡
献
,
那
么
我
们
只
要
计
数
判
断
是
奇
偶
即
可
。
当第k位为1时,当a_i+a_j在区间[2^k,2^{k+1}-1]或[2^{k+1}+2^k,2^{k+2}-1]时,会对答案的第k位产生贡献,那么我们只要计数判断是奇偶即可。
当第k位为1时,当ai+aj在区间[2k,2k+1−1]或[2k+1+2k,2k+2−1]时,会对答案的第k位产生贡献,那么我们只要计数判断是奇偶即可。
对
于
计
数
,
我
们
只
要
枚
举
a
i
,
二
分
查
找
满
足
条
件
的
a
j
,
四
次
二
分
找
到
满
足
条
件
即
可
对于计数,我们只要枚举a_i,二分查找满足条件的a_j,四次二分找到满足条件即可
对于计数,我们只要枚举ai,二分查找满足条件的aj,四次二分找到满足条件即可
#include <iostream>
#include <algorithm>
using namespace std;
int a[400005],b[400005];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
int ans = 0;
for (int k = 29; k >= 0; k--)
{
for (int i = 1; i <= n; i++)
{
b[i] = a[i] % (1<<(k+1));
}
//if( k == 1 ) cout << b[1] << ' ' << b[2] <<'\n';
sort(b+1,b+1+n);
int s = 0;
for (int i = 1; i <= n; i++)
{
int l = lower_bound(b+1,b+1+n,(1<<k)-b[i]) - b;
int r = upper_bound(b+1,b+1+n,(1<<(k+1))-1-b[i]) - b;
s += r - l;
l = lower_bound(b+1,b+1+n,(1<<(k+1))+(1<<k)-b[i]) - b;
r = upper_bound(b+1,b+1+n,(1<<(k+2))-1-b[i]) - b;
s += r - l;
if( 2 * b[i] & (1<<k) )
{
s --;
}
}
if( (s / 2) & 1 ) ans += (1<<k);
}
cout << ans << '\n';
return 0;
}