思路:
前缀和sum[i]保存前i个数的异或值,sum[i]=sum[i-1]^a[i],[L,r]的异或值显然是sum[r]^sum[L-1]。
试着枚举右端点i从1到n,得到以i为右端点的全部全部区间的异或值。
为避免重复可以二分一下,同时枚举全部以i+1为左端点的全部区间的异或值,如果和前面的值相等就加上相等的区间个数。
因为n比较小 (n^2)可以过。
注意:ans比较大,要开ll
Code:
#include<bits/stdc++.h>
#define js ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
int a[1005],n,sum[1005],ans;
int mp[200005];
int main() {
js;
cin>>n;
for(int i=1;i<=n;++i) {
cin>>a[i];
sum[i]=sum[i-1]^a[i];
}//前缀和
for(int i=1;i<=n;++i) {//枚举右端点, 中点
for(int j=1;j<=i;++j)
++mp[sum[i]^sum[j-1]];
for(int j=i+1;j<=n;++j)//枚举后面的区间避免重复
ans+=mp[sum[j]^sum[i]];//sum[j]^sum[i]相当于区间[i+1,j]的异或值
}
cout<<ans<<endl;
}
京公网安备 11010502036488号