这种出现异或的题一般来说都是进行二进制拆位,然后按位考虑的.
我们考虑第 $i$ 位是否为 1.
不妨模 $2^{i+1}$,排除前面的影响.
那么一对 $a[k]+b[k]$ 中第 $i$ 位为 1 的条件是:
1. 由后面进位,得 $i$ 位为 1.
2. 两个位置都是 1,但是进位后还是 1.
然后我们发现满足不等式 $2^i <=a[k]+b[k] < 2^{i+1}$ 或 $3 \times 2^i <= a[k]+b[k] < 4 \times 2^i$.
然后这个可以枚举 $a$,二分求 $b$ 的范围.
code:
#include <bits/stdc++.h>
#define N 400008
#define ll long long
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
int a[N],b[N],c[N],d[N];
int main()
{
// setIO("input");
int i,j,n;
scanf("%d",&n);
for(i=1;i<=n;++i)
scanf("%d",&a[i]);
for(i=1;i<=n;++i)
scanf("%d",&b[i]);
int ans=0,pow=1;
for(i=0;i<=28;++i)
{
for(j=1;j<=n;++j)
c[j]=a[j],d[j]=b[j];
for(j=1;j<=n;++j)
{
c[j]%=(pow<<1);
d[j]%=(pow<<1);
}
sort(d+1,d+1+n);
int l,r,sum=0;
for(j=1;j<=n;++j)
{
l=lower_bound(d+1,d+1+n,pow-c[j])-d;
r=lower_bound(d+1,d+1+n,2*pow-c[j])-d;
if(d[r]>=2*pow-c[j])
--r;
if(r>n)
--r;
if(l<=r)
sum+=(r-l+1);
l=lower_bound(d+1,d+1+n,3*pow-c[j])-d;
r=lower_bound(d+1,d+1+n,4*pow-c[j])-d;
if(d[r]>=4*pow-c[j])
--r;
if(r>n)
--r;
if(l<=r)
sum+=(r-l+1);
}
if(sum&1)
ans+=pow;
pow*=2;
}
printf("%d\n",ans);
return 0;
}