2020牛客寒假算法基础训练营4 D
子段异或
https://ac.nowcoder.com/acm/contest/3005/D
看到区间异或和就想起来了前缀。
前置知识:(下面的[xx,yy]代表从xx到yy的异或和)
所以有:
所以预处理出所有的前缀异或和即可,由于需要,故
这里可不用map,直接sort一遍即可使得相同的值相邻,然后记录这种区间的个数。由于要在所有异或和相同的区间中选择两个区间,
贡献即:,遍历一遍即可。
又因为,故
最小为0,所以从遍历是从0到n的。(all表示前缀异或和,all[0]初始化为0)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
int q[N], n;
int all[N];
ll ans = 0;
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++){
scanf("%d", &q[i]);
all[i] = all[i - 1] ^ q[i];
}
sort(all + 1, all + 1 + n);
for(int i = 0; i <= n; ) {
int j = i + 1; ll t = 1;
while(j <= n && all[i] == all[j]) j++, t++;
ans += (t - 1) * t / 2;
i = j;
}
printf("%lld\n", ans);
return 0;
}
查看10道真题和解析