题目大意
询问区间出现次数为偶数的数的异或和。
解题思路
求所有数的前缀异或和,再用线段树离线求出所有询问区间的不同数的异或和。
int n, m, a[maxn];
int sum[maxn];
vector<P> q[maxn];
int tr[maxn<<2], ans[maxn];
map<int, int> lst;
void update(int rt, int l, int r, int p, int v) {
if (l==r) {
tr[rt] ^= v;
return;
}
int mid = (l+r)>>1;
if (p<=mid) update(rt<<1, l, mid, p, v);
else update(rt<<1|1, mid+1, r, p, v);
tr[rt] = tr[rt<<1]^tr[rt<<1|1];
}
int ask(int rt, int l, int r, int L, int R) {
if (l>=L && r<=R) return tr[rt];
int mid = (l+r)>>1;
int sum = 0;
if (L<=mid) sum ^= ask(rt<<1, l, mid, L, R);
if (R>mid) sum ^= ask(rt<<1|1, mid+1, r, L, R);
return sum;
}
int main() {
IOS;
cin >> n;
for (int i = 1; i<=n; ++i) cin >> a[i], sum[i] = sum[i-1]^a[i];
cin >> m;
for (int i = 1; i<=m; ++i) {
int l, r; cin >> l >> r;
q[r].push_back({l, i});
}
for (int i = 1; i<=n; ++i) {
if (lst[a[i]]) update(1, 1, n, lst[a[i]], a[i]);
lst[a[i]] = i;
update(1, 1, n, i, a[i]);
for (auto v : q[i]) {
int res = ask(1, 1, n, v.x, i);
ans[v.y] = res^sum[i]^sum[v.x-1];
}
}
for (int i = 1; i<=m; ++i) cout << ans[i] << endl;
return 0;
}