题意:
给一个长度为
的序列
要求计算
我们分析答案的每一位,如果答案的第 位是 ,这意味着有奇数个 满足 的第 位是
首先我们要砍掉高于
位的信息(这对答案不产生影响),即让
,于是第
位是
的
的值只能在区间
中
这时如果固定
的值,
的值的区间就是
,因此能在排序后用二分快速计算满足
的第
位是
的
的个数。
AC代码:
int n, m, k;
int res, cnt, ans;
const int N = 4e5 + 10;
int a[N];
int b[N];
int main()
{
sd(n);
rep(i, 1, n)
sd(a[i]);
ans = 0;
rep(i, 0, 26)
{ //a[i]一定小于1<<26
int mod = 1 << (i + 1);
rep(j, 1, n)
b[j] = a[j] % mod;
int s = 0;
sort(b + 1, b + n + 1);
rep(j, 1, n)
{
int l, r;
l = lower_bound(b + 1, b + n + 1, (1 << i) - b[j]) - b;
r = lower_bound(b + 1, b + n + 1, (1 << (i + 1)) - b[j]) - b - 1;
s += (r - l + 1); //统计2^i到2^(i+1)-1区间内的解
l = lower_bound(b + 1, b + n + 1, (1 << i) + (1 << (i + 1)) - b[j]) - b;
r = lower_bound(b + 1, b + n + 1, (1 << (i + 2)) - b[j]) - b - 1;
s += (r - l + 1); //统计2^(i+1)+2^i到2^(i+2)-1区间内的解
if ((b[j] + b[j]) & (1 << i))
s--; //自己和自己相加的不算
}
if ((s / 2) & 1)
ans += 1 << i; //小于j和大于j的都记录了所以个数要除以2
}
pd(ans);
return 0;
}