Codeforces 1113C. Sasha and a Bit of Relax 题解

原题链接:Codeforces 1113C. Sasha and a Bit of Relax
题目大意:给定一个长度为\(n\)的数列\(a_1,a_2,\cdots,a_n\),然后,求数列中有多少个满足一下性质的\([l,r]\)

  1. \(r-l+1\)是偶数
  2. \(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;
}

原文地址:https://www.cnblogs.com/withhope/p/10392012.html