codefoces 1323D - Present
https://codeforces.com/problemset/problem/1323/D
思路
这道题暴力求解的复杂的是\(O(n^2)\)一定不可行,考虑对于二进制的每一位求解。
对于最终答案的每一位,只有两两之和为1的个数达到奇数个,这一位是1,否则是0。
设现在要求答案第i位,那么比i位高的位数没有影响,通过取模(1<<(i+1))去掉。
随后进行排序,这是为了再接下来通过二分统计两两之和为1的个数。
对于取模后,两两之和如果想要是1,取值范围是[ (1<<i), (1<<(i+1)) ) 或者 [ (1<<i)+(1<<(i+1)), (1<<(i+2)) ),通过二分统计出两两之和为1的个数。
代码
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int n;
int a[400005];
int b[400005];
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin >> n;
for(int i=1;i<=n;++i)
cin >> a[i];
int ans = 0;
for(int i=0;i<=25;++i)
{
int mod = 1 << (i + 1);
for(int j=1;j<=n;++j)
b[j] = a[j] % mod;
sort(b+1,b+1+n);
int l,r,num = 0;
for(int j=1;j<=n;++j)
{
l = lower_bound(b+1, b+1+n, (1<<i)-b[j]) - b;
r = lower_bound(b+1, b+1+n, (1<<(i+1))-b[j]) - b;
num += (r - l);
l = lower_bound(b+1, b+1+n, (1<<i)+(1<<(i+1))-b[j]) - b;
r = lower_bound(b+1, b+1+n, (1<<(i+2))-b[j]) - b;
num += (r - l);
if((b[j]+b[j])&(1<<i))
num--;
}
if((num/2)&1)
ans += (1 << i);
}
cout << ans << endl;
return 0;
}