1^1=0 0^0=0
1^0=1 0^1=1
可知子集前半部分和后半部分异或和相等且(a^x)^x=a;a=(k~i)的前缀和,x为(1到k)的前缀和
所以只需要找到与当前序列的前缀异或和值相等的子数组异或和即可,
朴素法是枚举到i时从1到i找到与当前前缀和相等的值,时间复杂度为,明显会超时,
我们可用一个数组记录一下当前某个 1到k的异或和 的出现次数,注意区分奇偶
#include <bits/stdc++.h>
using namespace std;
map<int, int> M1, M2;
int main()
{
int n;
scanf("%d", &n);
int sum = 0;
long long res = 0;
M2[0] ++ ;
for (int i = 1; i <= n; i ++ )
{
int x;
scanf("%d", &x);
sum ^= x;
if (i & 1)res += M1[sum] ++ ;
else res += M2[sum] ++ ;
}
printf("%lld", res);
return 0;
}