Codeforces Round #365 (Div. 2) D. Mishka and Interesting sum 树状数组
D. Mishka and Interesting sum
链接:
http://codeforces.com/problemset/problem/703/D
题意:
给一个序列 每次询问一个区间 求区间中出现次数为偶数次的数的异或和
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<map> 5 using namespace std; 6 7 struct Query { 8 int l, r, id; 9 bool operator<(const Query &a)const { 10 return r < a.r; 11 } 12 }; 13 14 const int maxn = 1000000 + 10; 15 int a[maxn], pre[maxn], ans[maxn], tree[maxn]; 16 Query q[maxn]; 17 18 void add(int k, int num) 19 { 20 while (k < maxn){ 21 tree[k] ^= num; 22 k += k&-k; 23 } 24 } 25 26 int sum(int k) 27 { 28 int sum = 0; 29 while (k){ 30 sum ^= tree[k]; 31 k -= k&-k; 32 } 33 return sum; 34 } 35 36 int main() 37 { 38 int n; 39 cin >> n; 40 for (int i = 1; i <= n; i++) { 41 scanf("%d", &a[i]); 42 pre[i] = pre[i - 1] ^ a[i]; 43 } 44 int m; 45 cin >> m; 46 for (int i = 1; i <= m; i++) { 47 scanf("%d%d", &q[i].l, &q[i].r); 48 q[i].id = i; 49 } 50 sort(q + 1, q + 1 + m); 51 map<int, int>vis; 52 int t = 1; 53 for (int i = 1; i <= n; i++) { 54 if (vis[a[i]]) 55 add(vis[a[i]], a[i]); 56 vis[a[i]] = i; 57 add(i, a[i]); 58 while (q[t].r <= i && t <= m) { 59 int l = q[t].l - 1, r = q[t].r; 60 ans[q[t].id] = sum(l) ^ sum(r) ^ pre[l] ^ pre[r]; 61 t++; 62 } 63 } 64 for (int i = 1; i <= m; i++) 65 printf("%d\n", ans[i]); 66 return 0; 67 }