牛客3005D-子段异或-前缀+map

链接: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;
}
发布了144 篇原创文章 · 获赞 135 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Nothing_but_Fight/article/details/104267899