题目:

给定一个长度为n的整数数组,问有多少对互不重叠的非空区间,使得两个区间内的数的异或和为0。
1<=n<=1000,0<=数组元素<100000。


做法:

首先预处理出数组,表示这个区间元素的和。
这样我们就可以得到任意区间的和。[l,r]区间的xor和 = prefix[r]^prefix[l-1]。
设选出的互不重叠区间对为A、B,且A在B左侧。
我们枚举B的左端点x。此时我我们已经记录下了所有右端点小于x的区间,也就是合法的A已经全部记录下来了。则对于每个x,我们再枚举右端点y,看有几个A能匹配就行了。枚举完x后,将右端点为x的区间记录一下,因为下一次我们将枚举x+1。以x为右端点的区间可以作为合法的A。


代码:

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false), cin.tie(0)
#define debug(a) cout << #a ": " << a << endl
using namespace std;
typedef long long ll;
const int N = 2e5 + 7;
int a[1010], prefix[1010], mp[N];
int main(void){
    IOS;
    int n; cin >> n;
    for (int i = 1; i <= n; ++i){
        cin >> a[i];
        prefix[i] = prefix[i-1]^a[i];
    }    
    ll ans = 0;
    for (int i = 1; i <= n; ++i){
        for (int j = i; j <= n; ++j){
            int x = prefix[j]^prefix[i-1];
            ans += mp[x];
        }
        for (int j = 1; j <= i; ++j){
            int x = prefix[i]^prefix[j-1];
            mp[x]++;
        }
    }
    cout << ans << endl;
    return 0;
}