Description
传送门
给定n个数, m个询问, 求\([l, r]\)内出现次数为偶数的数字异或和.
n,m <= 1000000
Solution
考虑出现次数为偶数的怎么求: 直接用全部的异或和异或上出现的元素的异或和.
第一部分我们采用前缀异或和来处理.
第二部分我们用树状数组来维护.
考虑询问离线,按右端点排序.
制造一条扫描线.从左到右扫,如果遇到一个已经处理的元素就把它从树状数组中消除然后再把这个位置上的值加上.
Code
#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
#define drep(i, a, b) for(int i = (a), i##_end_ = (b); i >= i##_end_; --i)
#define clar(a, b) memset((a), (b), sizeof(a))
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define Debug(s) debug("The massage in line %d, Function %s: %s\n", __LINE__, __FUNCTION__, s)
typedef long long LL;
typedef long double LD;
const int BUF_SIZE = (int)1e6 + 10;
struct fastIO {
char buf[BUF_SIZE], buf1[BUF_SIZE];
int cur, cur1;
FILE *in, *out;
fastIO() {
cur = BUF_SIZE, in = stdin, out = stdout;
cur1 = 0;
}
inline char getchar() {
if(cur == BUF_SIZE) fread(buf, BUF_SIZE, 1, in), cur = 0;
return *(buf + (cur++));
}
inline void putchar(char ch) {
*(buf1 + (cur1++)) = ch;
if (cur1 == BUF_SIZE) fwrite(buf1, BUF_SIZE, 1, out), cur1 = 0;
}
inline void flush() {
if (cur1 > 0) fwrite(buf1, cur1, 1, out);
cur1 = 0;
}
}IO;
#define getchar IO.getchar
#define putchar IO.putchar
int read() {
char ch = getchar();
int x = 0, flag = 1;
for(;!isdigit(ch); ch = getchar()) if(ch == '-') flag *= -1;
for(;isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
return x * flag;
}
void write(LL x) {
if(x >= 10) write(x / 10);
putchar(x % 10 + 48);
}
#define Maxn 1000009
namespace BIT{
int c[Maxn];
#define lowbit(x) ((x) & (-(x)))
inline void modify(int pos, int val) {
for(;pos < Maxn; pos += lowbit(pos)) c[pos] ^= val;
}
inline int query(int pos) {
int res = 0;
for(;pos; pos -= lowbit(pos)) res ^= c[pos];
return res;
}
inline int query(int l, int r) {
return query(r) ^ query(l - 1);
}
}
struct queries {
int l, r, id;
int operator < (const queries a) const {
/**/ return r < a.r;
}
}q[Maxn];
int n, a[Maxn], sufXor[Maxn], m, ans[Maxn];
map <int, int> lst;
int main() {
#ifdef Qrsikno
freopen("CF703D.in", "r", stdin);
freopen("CF703D.out", "w", stdout);
#endif
n = read();
rep(i, 1, n) a[i] = read(), sufXor[i] = sufXor[i - 1] ^ a[i];
m = read();
/**/rep(i, 1, m) q[i].l = read(), q[i].r = read(), q[i].id = i;
sort(q + 1, q + m + 1);
int pos = 1;
rep(i, 1, m) {
for(; pos <= q[i].r; ++pos) {
/**/ if(lst[a[pos]]) BIT :: modify(lst[a[pos]], a[pos]);
lst[a[pos]] = pos;
BIT :: modify(pos, a[pos]);
}
ans[q[i].id] = BIT :: query(q[i].l, q[i].r) ^ sufXor[q[i].r] ^ sufXor[q[i].l - 1];
}
rep(i, 1, m) write(ans[i]), putchar('\n');
IO.flush();
#ifdef Qrsikno
cerr << clock() * 1.0 / CLOCKS_PER_SEC << endl;
#endif
return 0;
}