前缀异或和一边计数即可。
枚举i为已经计数的区间右边界,然后以i为左端点,看后面的区间有多少个区间异或和是已经计数的加上即可。
对于区间右边界的更新,假设现在已有a、b、c 现在加入一个d,产生的贡献就是[a,d]、[b、d]、[c、d]、[d,d]新增的四个区间 根据a^b=c b=a^c 可以用前缀和之间进行异或得到
注意数组大小应该开到(1<<17)-1 因为(1<<16)<1e5
#include<bits/stdc++.h> using namespace std; int mp[1<<17]; int sum[1<<10]; int main(){ int n;cin>>n; for(int i=1;i<=n;i++){ int x;cin>>x; sum[i]=sum[i-1]^x; } long long ans=0; for(int i=1;i<=n;i++){//i为边界枚举 for(int j=0;j<i;j++) mp[sum[i]^sum[j]]++;//更新已经计算的区间 for(int j=i+1;j<=n;j++) ans += mp[sum[i]^sum[j]];///后面以i为左边界的区间的异或和 前面被更新过多少次 } cout<<ans; return 0; }