CF703D Mishka and Interesting sum

题意:给定一个1e6长度的值域1e9的数组。每次给定询问,询问区间内出现偶数次的数的异或和。

题解:首先很显然,每一次询问的答案,等于这个区间所有不同元素异或和异或上区间异或和。(因为出现偶数次的对区间异或和贡献为0,此时剩下的是出现奇数次的数,在取个补集即为答案)

区间异或和前缀和就好了,那问题转化为求区间不同元素异或和。由于这个东西区间合并很困难,所以在线算法是比较不优雅的。那我们考虑离线算法。我们按询问的右端点为第一关键字排序,然后处理到目前这个右端点位置的last数组,last数组定义为每个数最后出现的位置,然后给每个值对应的last附上它的值,这样我们一个区间求异或和可以得到区间不同元素异或和。树状数组一发就好了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 1000000
 4 #define LL long long
 5 #define lowbit(x) ((x) & -(x))
 6
 7 inline LL read() {
 8     LL x = 0, f = 1; char a = getchar();
 9     while(a < ‘0‘ || a > ‘9‘) { if(a == ‘-‘) f = -1; a = getchar(); }
10     while(a >= ‘0‘ && a <= ‘9‘) x = x * 10 + a - ‘0‘, a = getchar();
11     return x * f;
12 }
13
14 int n, a[N + 5], ans[N + 5], sum[N + 5], Q;
15 int fen[N + 5];
16 map<int, int> last;
17
18 struct query {
19     int id, l, r;
20     bool operator < (const query & w) const {
21         return r < w.r;
22     }
23 } q[N + 5];
24
25 inline void add(int pos, int val) { if(!pos) return; for(int i = pos; i <= n; i += lowbit(i)) fen[i] ^= val; }
26
27 inline int querysum(int l, int r) {
28     int ret = 0;
29     for(int i = r; i; i -= lowbit(i)) ret ^= fen[i];
30     for(int i = l - 1; i; i -= lowbit(i)) ret ^= fen[i];
31     return ret;
32 }
33
34 int main() {
35     n = read();
36     for(int i = 1; i <= n; i++) a[i] = read();
37     for(int i = 1; i <= n; i++) sum[i] = sum[i - 1] ^ a[i];
38     Q = read();
39     for(int i = 1; i <= Q; i++) q[i].id = i, q[i].l = read(), q[i].r = read();
40     sort(q + 1, q + 1 + Q);
41     for(int pos = 1, i = 1; i <= Q; i++) {
42         for(; pos <= q[i].r; pos++) {
43             add(last[a[pos]], a[pos]);
44             last[a[pos]] = pos;
45             add(pos, a[pos]);
46         }
47         ans[q[i].id] = querysum(q[i].l, q[i].r) ^ sum[q[i].l-1] ^ sum[q[i].r];
48     }
49     for(int i = 1; i <= Q; i++) printf("%d\n", ans[i]);
50     return 0;
51 }
时间: 2024-08-04 02:37:04

CF703D Mishka and Interesting sum的相关文章

codeforces 703D D. Mishka and Interesting sum(树状数组)

题目链接: D. Mishka and Interesting sum time limit per test 3.5 seconds memory limit per test 256 megabytes input standard input output standard output Little Mishka enjoys programming. Since her birthday has just passed, her friends decided to present h

CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组(转)

转载自:http://www.cnblogs.com/icode-girl/p/5744409.html 题目链接:CF #365 (Div. 2) D - Mishka and Interesting sum 题意:给出n个数和m个询问,(1 ≤ n, m ≤ 1 000 000) ,问在每个区间里所有出现偶数次的数异或的值. 思路:容易想到,把区间内的所有的数都异或得到的是出现奇数次的数的值,然后再异或该区间内的所有出现过的数(每个数只统计一次),得到的ans了. 第一个问题:得到询问区间的

CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组

题目链接:CF #365 (Div. 2) D - Mishka and Interesting sum 题意:给出n个数和m个询问,(1 ≤ n, m ≤ 1 000 000) ,问在每个区间里所有出现偶数次的数异或的值. 思路:容易想到,把区间内的所有的数都异或得到的是出现奇数次的数的值,然后再异或该区间内的所有出现过的数(每个数只统计一次),得到的ans了. 第一个问题:得到询问区间的所有数的异或值,由 a[l~r] ^ a[0~(l-1)] = a[l~r] 可以用数组all_xor[i

Codeforces Round #365 (Div. 2) D.Mishka and Interesting sum 树状数组+离线

D. Mishka and Interesting sum time limit per test 3.5 seconds memory limit per test 256 megabytes input standard input output standard output Little Mishka enjoys programming. Since her birthday has just passed, her friends decided to present her wit

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 str

[树状数组]Mishka and Interesting sum(codeforces703D)

Mishka and Interesting sum time limit per test 3.5 seconds memory limit per test 256 megabytes input standard input output standard output Little Mishka enjoys programming. Since her birthday has just passed, her friends decided to present her with a

codeforces 703D Mishka and Interesting sum 偶数亦或 离线+前缀树状数组

题目传送门 题目大意:给出n个数字,m次区间询问,每一次区间询问都是询问 l 到 r 之间出现次数为偶数的数 的亦或和. 思路:偶数个相同数字亦或得到0,奇数个亦或得到本身,那么如果把一段区间暴力亦或,得到的其实就是出现次数为奇数的数字的亦或和,所以我们希望这段区间内的所有数字出现次数都+1,使奇偶性互换. 我们先处理出前缀的亦或和,这样可以得到次数为奇数的亦或和. 接下来的问题就是要改变一段区间的奇偶性了,也就是说,这个问题其实就转化成了如何求一段区间出现的所有数字(无重复). 这里我学到的是

Codeforces Round #365 (Div. 2) D - Mishka and Interesting sum(离线树状数组)

http://codeforces.com/contest/703/problem/D 题意: 给出一行数,有m次查询,每次查询输出区间内出现次数为偶数次的数字的异或和. 思路: 这儿利用一下异或和的性质,在一个区间中,我们如果把所有数字都异或的话,可以发现最后偶数次的数字异或后都变成了0,只剩下了奇数次的数字异或. 举个例子,{1,2,3,2,3,5} 异或和是1^2^3^2^3^5=1^5 因为最后要计算偶数次数字的异或和,那么最后我们只需要再异或上该区间内所有不同数字即可. 那么我们可以先

Codeforces Round #365 (Div. 2) D.Mishka and Interesting sum

题目链接:传送门 题目大意:给n个数,m次询问,每次询问区间 l,r 内出现偶数次数的异或和 题目思路:前缀和+离线处理+树状数组 首先可以知道, l,r 内出现奇数次的数的和,就是把 l,r内所有数异或起来就是答案,那么出现偶数次的数就可以 先求出区间 l,r 内有多少不同的数,将这些数异或起来,再异或上区间内出现奇数次的数的异或和就是答案.(出现偶数次的数异或后为0,奇数次的数异或后是本身   然后离线处理询问,对询问按右端点 sort,因为树状数组保存的是数出现的最后位置.离线处理询问后便