链接:https://ac.nowcoder.com/acm/contest/3005/D
来源:牛客网
题目描述:
输入一个数列a,你需要输出其中异或值为0的不同子段的数量。一个子段 [l,r] (1≤l≤r≤n)的异或值为al⊕al+1⊕al+2⊕…⊕ar,其中⊕符号代表异或运算。
两个子段被视为相同的,当且仅当其开始和结束位置均对应相同。
输入描述:
第一行一个整数 n ,代表数列长度。
第二行 n 个整数,代表数列。
输出描述:
输出一个整数,代表答案。
输入样例:
5
1 2 3 2 1
输出样例:
2
核心思想:
定义k前缀异或值:前k个数的异或值。
一个子段 [l,r] 的异或值为0,当且仅当l-1前缀异或值==r前缀异或值
用STL的map[i]表示前缀异或值i出现的次数,遍历数组,累加并更新map即可。
代码如下:
#include<cstdio>
#include<iostream>
#include<map>
using namespace std;
typedef long long ll;
const int N=2e5+20;
map<int,int>mp;
int main()
{
int n,x,t=0;//t为前缀异或值
ll ans=0;
cin>>n;
mp[0]=1;//初始化0的时候
while(n--)
{
scanf("%d",&x);
t^=x;
ans+=mp[t];//累加
mp[t]++;//更新
}
cout<<ans<<endl;
return 0;
}