关于异或运算,有以下性质:
① 0^a=a
② a^a=0
③ a^b^b=a
④ a^b=c => a^b^b = c^b => a=c^b
⑤ sum[i]表示i结尾的异或前缀和
sum[l-r]=sum[r]^sum[l-1]
利用以上性质,可以将原问题转换为两端点的异或前缀和要相等。
#include<bits/stdc++.h>
using namespace std;
#pragma warning(disable:4996);
#define int long long
#define endl '\n'
#define rep(j,b,e) for(int j=(b);j<=(e);j++)
#define drep(j,e,b) for(int j=(e);j>=(b);j--)
const int N = 2e5 + 10;
int mod = (1e7) + 7;
int T = 1;
int n, m, x, k;
vector<int>arr(1);
vector<int>ans;
signed main() {
#ifndef ONLINE_JUDGE
//freopen("out.txt", "w", stdout);
#endif
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
//|____|___|
//s-2m s-m s
//s^s-m=s-m^s-2m =>s^s-2m=s-m^s-m=0 =>s=s-2m
cin >> n;
unordered_map<int, int>even, odd;
rep(j, 1, n) {
cin >> k;
arr.push_back(arr[j-1]^k);//异或前缀和
}
int ans = 0;
even[0]++;
rep(j, 1, n) {
k = arr[j];
if (j % 2 == 0) {
ans += even[k];
}
else {
ans += odd[k];
}
if (j % 2 == 0)even[k]++;
else odd[k]++;
}
//区间长为偶,须左右端点同奇同偶
cout << ans << endl;
}