补题链接:Here
题意:选取任意不重叠的两个区间,使异或结果为 (0)
样例:(1,2,3,4,5,5)
在样例中我们可以选取 (1,2,3) 和 (5,5) 就是满足题意
思路:相同元素的异或为 (0) ,所以我们找到两个点 (i - j) ,与 (i -j) 相同答案的个数(这句话是废话....)
先求出异或前缀和,然后枚举每个位置,统计该位置之前的所有前缀和、即吧该位置作为右端点枚举计算右端点之前的所有位,为左端点计数。
同时当把该位当作右端点计算完之后,并用map存储,把该店当作左端点,逐个枚举右端点,用map查询相同的值,进行计数.
(1,2,3,4,5,6,7,8,8)
比如,当 (i) 运算到第一个 (8) 的时候,前面有 (1,2,3) 的异或值为 (0) ,且已经记录,然后当第一个 (8) 为右端点运算结束之后,变为左端点是,第一个 (8) 和第二个 (8) 异或结果为 (0) ,并且此时还有前面 (1,2,3) 异或为 (0) , (累计数 +1)
using ll = long long;
const int N = 1e6 + 10;
ll n, x, ans, a[N], b[N];
void solve() {
cin >> n;
for (ll i = 1; i <= n; ++i) {
cin >> x;
a[i] = a[i - 1] ^ x;
}
for (ll i = 1; i <= n; ++i) {
for (ll j = 0; j < i; ++j) b[a[i] ^ a[j]]++;
for (ll j = i + 1; j <= n; ++j)
ans += b[a[i] ^ a[j]];
}
cout << ans << "
";
}