异或前缀和
知识点 : 前缀和 哈希表
子数组异或和
给定一个长度为 n 的整数数组 a 1 , a 2 , … , a n 。 a_1,a_2,…,a_n。 a1,a2,…,an。
请你统计一共有多少个数组 a 的非空连续子数组能够同时满足以下所有条件:
- 该连续子数组的长度为偶数。
- 该连续子数组的前一半元素的异或和等于其后一半元素的异或和。
例如,当给定数组为 [ 1 , 2 , 3 , 4 , 5 ] [1,2,3,4,5] [1,2,3,4,5]时,满足条件的连续子数组只有 1 个: [ 2 , 3 , 4 , 5 ] [2,3,4,5] [2,3,4,5]。
输入格式
第一行包含整数 n。
第二行包含 n 个整数 a 1 , a 2 , … , a n 。 a_1,a_2,…,a_n。 a1,a2,…,an。
输出格式
一个整数,表示满足条件的连续子数组的数量。
数据范围
前三个测试点满足 2≤n≤10
所有测试点满足
2
≤
n
≤
3
×
1
0
5
,
0
≤
a
i
<
2
20
2≤n≤3×10^5 , 0≤a_i<2^{20}
2≤n≤3×105,0≤ai<220
输入样例1:
5
1 2 3 4 5
输出样例1:
1
输入样例2:
6
3 2 2 3 7 6
输出样例2:
3
输入样例3:
3
42 4 2
输出样例3:
0
#include<iostream>
#include<unordered_map>
using namespace std;
int n;
const int N=3e5+10;
int s[N];
long long ans;
int main(){
scanf("%d",&n);
int x,sum;
unordered_map<int,int>mp[2];
mp[0][0]++;
for(int i=1;i<=n;i++){
scanf("%d",&x);
sum^=x;//异或前缀和
ans+=mp[i&1][sum];//奇减奇,偶减偶,保证个数是偶数
mp[i&1][sum]++;
}
cout<<ans;
return 0;
}