题解:AT_abc365_e [ABC365E] Xor Sigma Problem
奇迹般地独立过了 E 题,发篇题解纪念一下。
注:本文中均使用小写字母作变量名,请注意与题目的微小区别。
不难想到维护前缀异或和(此处记
直接暴力求解是
因为这是位运算,不难想到按位考虑。记
代码如下(比较通俗易懂):
#include<bits/stdc++.h>
using namespace std;
inline long long read(){
long long ans=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') f=-f;
c=getchar();
}
while(c>='0'&&c<='9'){
ans=(ans<<3)+(ans<<1)+c-48;
c=getchar();
}
return ans*f;
}
void write(long long x){
if(x<0){
putchar('-');
x=-x;
}
if(x<10) putchar(x+48);
else{
write(x/10);
putchar(x%10+48);
}
}
long long n;
long long a[200005],b[200005];
long long g[35][2];
long long ans;
signed main(){
n=read();
for(long long i=1;i<=n;i++){
a[i]=read();
b[i]=a[i]^b[i-1];
}
for(long long i=0;i<=28;i++) g[i][0]++;//将b[0]加进去
for(long long i=1;i<=n;i++){
for(long long j=0;j<=28;j++){
ans+=g[j][bool((b[i])&(1<<j))^1]*(1<<j);//按位统计答案
}
for(long long j=0;j<=28;j++){
g[j][bool((b[i])&(1<<j))]++;//按位更新g数组
}
}
for(long long i=1;i<=n;i++) ans-=a[i];//除去长度为1的区间
write(ans);
return 0;
}
小插曲:赛时我把 __int128,赛后才发现 long long 就够了。