原题链接:Codeforces 1113C. Sasha and a Bit of Relax
题目大意:给定一个长度为\(n\)的数列\(a_1,a_2,\cdots,a_n\),然后,求数列中有多少个满足一下性质的\([l,r]\)
- \(r-l+1\)是偶数
- 令\(mid=\frac{r-l+1}{2}\),则有\(a_1\oplus a_2\oplus \cdots \oplus a_{mid}=a_{mid+1}\oplus a_{mid+2}\oplus \cdots\oplus a_r\)
(注:\(\oplus\)在C++中就是异或的意思,也就是^)
题解:我们知道,对于\(\oplus\)操作,我们是可以用前缀和的,那么,我们令\(sum_i\)表示从\(1\)到\(i\)的异或和,那么,我们要求的便是\(sum_{l-1}\oplus sum_{mid}\)和\(sum_{mid}\oplus sum_r\)。
它们之间如果相等便可以添加至答案,列出式子\(sum_{l-1}\oplus sum_{mid}=sum_{mid}\oplus sum_r\),很明显\(sum_{mid}\)在左右两边约掉了,所以,原式就变成了\(sum_{l-1}=sum_r\)。
好了,接下来就很简单了,看代码吧:(记得要用long long)
#include <cstdio>
#include <iostream>
using namespace std;
#define Maxn 300000
#define ll long long
int a[Maxn+5];
int sum[Maxn+5];
int num[(1<<20)+5][2];
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
sum[i]=sum[i-1]^a[i];
}
num[0][0]++;
ll ans=0;
for(int i=1;i<=n;i++){
ans+=num[sum[i]][i&1];
num[sum[i]][i&1]++;
}
cout<<ans<<endl;
return 0;
}