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 }

 

posted @ 2016-09-27 13:49  Flowersea  阅读(226)  评论(12编辑  收藏  举报