题目链接:
http://codeforces.com/contest/703/problem/D
D. Mishka and Interesting sum
memory limit per test 256 megabytes
题意
求一个区间内所有出现次数为偶数次的数的异或和。
题解
如果题目叫我们求区间内所有出现次数为奇数次的数的异或和,那就好办了,直接把区间所有的数都异或起来就可以了。
现在我们把问题转换一下:我们先求出所有的数的异或和sum1,然后再求出区间内所有不同的数的异或和sum2,那么ans=sum1^sum2.
对于sum1可以O(n)跑前缀异或和,也可以跑线段树。而对于sum2我们可以用离线的线段树来处理(搓这里)。
代码
#include<iostream>
#include<cstdio>
#include<map>
#include<algorithm>
#include<cstring>
#define lson (o<<1)
#define rson ((o<<1)|1)
#define M l+(r-l)/2
#define X first
#define Y second
#define mkp make_pair
using namespace std;
const int maxn = 1e6 + 10;
const int maxq = 1e6 + 10;
typedef int LL;
LL sumv[maxn << 2],sumv2[maxn<<2];
map<int, pair<int,int> > mp;
int arr[maxn];
LL ans[maxq];
struct Node {
int l, r, id;
bool operator <(const Node& tmp) const {
return r < tmp.r;
}
} nds[maxq];
int ql, qr;
LL _sumv,_sumv2;
void query(int o, int l, int r) {
if (ql <= l&&r <= qr) {
_sumv ^= sumv[o];
_sumv2 ^= sumv2[o];
}
else {
if (ql <= M) query(lson, l, M);
if (qr>M) query(rson, M + 1, r);
}
}
int _p, _v;
void update(int o, int l, int r,int type) {
if (l == r) {
if(type==1) sumv[o] = _v;
else sumv2[o] = _v;
}
else {
if (_p <= M) update(lson, l, M,type);
else update(rson, M + 1, r,type);
if(type==1) sumv[o] = sumv[lson] ^ sumv[rson];
else sumv2[o] = sumv2[lson] ^ sumv2[rson];
}
}
int n;
void init() {
memset(sumv, 0, sizeof(sumv));
mp.clear();
}
int main() {
init();
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &arr[i]);
_p = i; _v = arr[i]; update(1, 1, n, -1);
}
int q;
scanf("%d", &q);
for (int i = 0; i < q; i++) {
scanf("%d%d", &nds[i].l, &nds[i].r);
nds[i].id = i;
}
sort(nds, nds + q);
int pos = 1;
for (int i = 0; i < q; i++) {
int l = nds[i].l, r = nds[i].r, id = nds[i].id;
while (pos <= r) {
if (mp.count(arr[pos])) {
_p = mp[arr[pos]].X, _v = 0;
update(1, 1, n,1);
}
mp[arr[pos]].X = pos;
_p = pos, _v = arr[pos];
update(1, 1, n,1);
pos++;
}
ql = l, qr = r;
_sumv = 0,_sumv2=0;
query(1, 1, n);
ans[id] = _sumv^_sumv2;
}
for (int i = 0; i < q; i++) {
printf("%d
", ans[i]);
}
return 0;
}