思路:
前缀和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; }