Codeforces #539 (Div. 1) A. Sasha and a Bit of Relax (异或 前缀和)
程序员文章站
2022-05-14 15:53:57
...
题目连接: https://codeforces.com/problemset/problem/1109/A
题目大意: 给定n个数 问有多少个偶数长度的区间l,r 使得mid=(l+r-1)/2,l到mid的数异或等于mid+1到r的异或
官方题解,很详细了 第一次学到异或还能求前缀和,斯巴拉西. 枚举区间的方法也是第一次学到.
sum[i]代表a1~ai的异或和, 那么题目等价于求多少对l~r 使得sum[l-1]=sum[r] 因为要求区间长度为偶数 当r为奇数时 l一定是偶数 那么l-1就是奇数,反过来也一样 .所以最后等价于 对当前枚举的i,i前面有多少与i奇偶性相同的sum[i],开了个map记录下就行.
唯一需要注意的就是 mp[0][0]的初始值为1,看了很多博客也没具体明白为什么 ,可能意思代表长度为0时异或为0也在数组中(猜的)
举个例子,输入为2
1 1
如果不初始化 最后答案就是0 因为当i等于2时 mp[0][0]为0 ans+=mp[0][0] 导致对答案没贡献
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<stdlib.h>
#include<algorithm>
#include<time.h>
#include<unordered_map>
#define bug1(g) cout<<"test: "<<g<<endl
#define bug2(g,i) cout<<"test: "<<g<<" "<<i<<endl
#define bug3(g,i,k) cout<<"test: "<<g<<" "<<i<<" "<<k<<endl
#define bug4(a,g,i,k) cout<<"test: "<<a<<" "<<g<<" "<<i<<" "<<k<<endl
using namespace std;
typedef long long ll;
unordered_map<int,int>mp[2];
int main()
{
ios::sync_with_stdio(0);
ll n,x,a,ans=0;
cin>>n;
mp[0][0]=1;
x=0;
for(int i = 1;i<=n;i++)
{
cin>>a;
x^=a;
ans+=mp[i%2][x];
++mp[i%2][x];
}
cout<<ans<<endl;
return 0;
}
上一篇: 关于编程的一些思考