题解:P11651 [COCI 2024/2025 #4] Xor
看到异或,我们首先应该想按位讨论。
那么我们就可以把某一位和它后面的位抽出来,去找它们加起来之后这一位为1的数有多少。
因此我们令
首先我们对这个序列排序,接下来我们就可以分类讨论需要加起来的两个数:第
其实不难发现,对于第
这题没卡双
#include<bits/stdc++.h>
#define int long long
#define mp make_pair
#define fi first
#define se second
#define lb lower_bound
#define fr front()
#define pii pair<int,int>
using namespace std;
int n,a[500005],b[500005];
signed main(){
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
int ans=0;
for(int k=30;k>=0;k--){
int res=0;
for(int i=1;i<=n;i++){
b[i]=a[i]&((1ll<<(k+1))-1);
}
sort(b+1,b+n+1);
int pos=n+1;
for(int i=1;i<=n;i++){
if(b[i]&(1ll<<k)){pos=i;break;}
}
// for(int i=1;i<=n;i++)cout<<b[i]<<" ";
// cout<<"\n";
//cout<<k<<" "<<pos<<" ";
for(int l=1;l<pos;l++){
if((2*b[l])&(1ll<<k)){
for(int i=l,j=l;i<pos;i++){
while(((b[j]+b[i])&(1ll<<k))&&j>=1)j--;
res+=i-j;
}
break;
}
}
//cout<<res<<"\n";
for(int i=pos,j=pos-1;i<=n;i++){
while(((b[j]+(b[i]^(1<<k)))&(1ll<<k))&&j>=1)j--;
res+=j;
}
//cout<<res<<"\n";
for(int l=pos;l<=n;l++){
if((2*(b[l]^(1ll<<k)))&(1ll<<k)){
for(int i=l,j=l;i<=n;i++){
while((((b[j]^(1<<k))+(b[i]^(1<<k)))&(1ll<<k))&&j>=pos)j--;
res+=i-j;
}
break;
}
}
//cout<<res<<"\n";
ans+=(res%2)*(1ll<<k);
}
cout<<ans;
}