Codeforces Round #365 (Div. 2) D 树状数组+离线处理

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 with array of non-negative integers a1, a2, ..., an of n elements!

Mishka loved the array and she instantly decided to determine its beauty value, but she is too little and can‘t process large arrays. Right because of that she invited you to visit her and asked you to process m queries.

Each query is processed in the following way:

  1. Two integers l and r (1 ≤ l ≤ r ≤ n) are specified — bounds of query segment.
  2. Integers, presented in array segment [l,  r] (in sequence of integers al, al + 1, ..., ar) even number of times, are written down.
  3. XOR-sum of written down integers is calculated, and this value is the answer for a query. Formally, if integers written down in point 2 are x1, x2, ..., xk, then Mishka wants to know the value , where  — operator of exclusive bitwise OR.

Since only the little bears know the definition of array beauty, all you are to do is to answer each of queries presented.

Input

The first line of the input contains single integer n (1 ≤ n ≤ 1 000 000) — the number of elements in the array.

The second line of the input contains n integers a1, a2, ..., an (1 ≤ ai ≤ 109) — array elements.

The third line of the input contains single integer m (1 ≤ m ≤ 1 000 000) — the number of queries.

Each of the next m lines describes corresponding query by a pair of integers l and r (1 ≤ l ≤ r ≤ n) — the bounds of query segment.

Output

Print m non-negative integers — the answers for the queries in the order they appear in the input.

Examples

input

33 7 811 3

output

0

input

71 2 1 3 3 2 354 74 51 31 71 5

output

03132

Note

In the second sample:

There is no integers in the segment of the first query, presented even number of times in the segment — the answer is 0.

In the second query there is only integer 3 is presented even number of times — the answer is 3.

In the third query only integer 1 is written down — the answer is 1.

In the fourth query all array elements are considered. Only 1 and 2 are presented there even number of times. The answer is .

In the fifth query 1 and 3 are written down. The answer is .

题意:给你n个数,m个区间询问 求区间出现次数为偶数次的数的异或和

题解:如果是奇数次呢?我们知道a^a=0 所以直接前缀异或和就可以处理。所以思考有没有一种反异或运算呢?自己模拟一遍发现这样是错误的。换一个思路考虑,将奇数次变为偶数次来处理,只需要计算出所要查询的区间内不同的数的异或和a 再 与这个区间的前缀异或和n做一次异或运算得到b,就能够将奇数次变为偶数次来处理(a^b=n可以得到b=a^n),那么如何快速计算一个区间内不同的数的异或和呢?离线处理,结构体存储每个查询区间的左右边界,按照右边界排序,从左向右遍历序列 树状数组维护 不断的将数添加到树状数组,若当前位置的数存在前驱,则删除前驱 (删除就是再进行一次异或a^a=0) 对于共右边界的查询区间 一次遍历得到答案,然后继续遍历。

 1 /******************************
 2 code by drizzle
 3 blog: www.cnblogs.com/hsd-/
 4 ^ ^    ^ ^
 5  O      O
 6 ******************************/
 7 //#include<bits/stdc++.h>
 8 #include<iostream>
 9 #include<cstring>
10 #include<cstdio>
11 #include<map>
12 #include<algorithm>
13 #include<queue>
14 #include<cmath>
15 #define ll __int64
16 #define PI acos(-1.0)
17 #define mod 1000000007
18 using namespace std;
19 int n,m;
20 int a[1000006];
21 int sum[1000006];
22 int tree[1000006];
23 int re[1000006];
24 int pre[1000006];
25 map<int,int>mp;
26 int lowbit(int t)
27 {
28     return t&(-t);
29 }
30 void add(int x,int y)
31 {
32     for(int i=x;i<=n;i+=lowbit(i))
33         tree[i]=tree[i]^y;
34 }
35 int getsum(int x)
36 {
37     int ans=0;
38     for(int i=x;i>0;i-=lowbit(i))
39        ans^=tree[i];
40     return ans;
41 }
42 struct node
43 {
44     int l,r;
45     int pos;
46 }N[1000006];
47 bool cmp(struct node aa,struct node bb)
48 {
49     return aa.r<bb.r;
50 }
51 int main()
52 {
53     scanf("%d",&n);
54     sum[0]=0;
55     mp.clear();
56     for(int i=1;i<=n;i++)
57     {
58         scanf("%d",&a[i]);
59         sum[i]=sum[i-1]^a[i];
60         pre[i]=mp[a[i]];
61         mp[a[i]]=i;
62     }
63     scanf("%d",&m);
64     for(int i=1;i<=m;i++)
65     {
66         scanf("%d %d",&N[i].l,&N[i].r);
67         N[i].pos=i;
68     }
69     sort(N+1,N+1+m,cmp);
70     int j=1;
71     for(int i=1;i<=m;i++)
72     {
73         for(;j<=n&&j<=N[i].r;j++)
74         {
75             if(pre[j])
76             add(pre[j],a[j]);
77             add(j,a[j]);
78         }
79 re[N[i].pos]=sum[N[i].r]^sum[N[i].l-1]^getsum(N[i].r)^getsum(N[i].l-1);
80     }
81     for(int i=1;i<=m;i++)
82         printf("%d\n",re[i]);
83     return 0;
84 }
时间: 2024-10-08 10:15:01

Codeforces Round #365 (Div. 2) D 树状数组+离线处理的相关文章

Codeforces Round #261 (Div. 2) D 树状数组应用

看着题意:[1,i]中等于a[i]的个数要大于[,jn]中等于a[j]的个数 且i<j,求有多少对这样的(i,j)  ,i<j但是 i前面的合法个数 要大于j后面的 看起来很像逆序数的样子,所以很容易往树状数组想去,但是处理就看个人了,像我比赛的时候就处理得非常的麻烦,虽做出了但是花时间也多,经过杰哥的教育,其实正着塞进树状数组 反着来找就可以了,灰常的简单清晰明了,贴一发纪念我的搓比 int n; int aa[1000000 + 55]; int bb[1000000 + 55]; int

Codeforces Round #225 (Div. 1) C 树状数组 || 线段树

看到这题很开心啊,有印象跟以前做过的很像,貌似最近就做过一个,以时间戳为区间来建立树状数组,然后一开始我以为题意是,给x点加val,它以下的所有节点都加-val:所以一开始就以 加 和 减 建立了两个树状数组,最后 减去就是答案,写完发现跟案例对不上啊,读了题目也没发现读错了,对于那句话 我理解错了,后来看了 这个: http://blog.csdn.net/keshuai19940722/article/details/18967661 仔细看看处理部分,我还以为分奇偶性有规律呢,后来才发现读

Codeforces Round #301 (Div. 2)(树状数组+离散化)

E. Infinite Inversions time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output There is an infinite sequence consisting of all positive integers in the increasing order: p?=?{1,?2,?3,?...}. We per

Codeforces Round #220 (Div. 2) D 树状数组 &amp;&amp; 二分

/*题目*/ 题意:给了n,m,然后一个包含m个数的数组nnum,数组默认从小到大排序,然后是 n个操作,输入一个数x,若x为0,把0加到这个字符串的末尾,若x为1,把1加到这个字符串的末尾,若x为-1,那么把字符串里的 下标 与 nnum数组里的元素相等的  给删除,字符串一开始是空的,问你最后字符串里有什么,若为空 就输出 POOR STACK 这题目看这操作一般都很容易联想到线段树,树状数组,一开始我建了个树状数组,但是超时了,毕竟操作很多,而且 在删除操作里,若nnum数组很大,等同于1

Educational Codeforces Round 10 D. Nested Segments (树状数组)

题目链接:http://codeforces.com/problemset/problem/652/D 给你n个不同的区间,L或者R不会出现相同的数字,问你每一个区间包含多少个区间. 我是先把每个区间看作整体,按照R从小到大排序.然后从最小的R开始枚举每个区间,要是枚举到这个区间L的时候,计算之前枚举的区间有多少个Li在L之后,那么这些Li大于L的区间的数量就是答案.那我每次枚举的时候用树状数组add(L , 1) 说明在L这个位置上出现了区间,之后枚举的时候计算L之前的和,然后i - 1 -

Codeforces 374D Inna and Sequence 二分+树状数组

题目链接:点击打开链接 给定n个操作,m长的序列a 下面n个数 if(co>=0)则向字符串添加一个co (开始是空字符串) else 删除字符串中有a的下标的字符 直接在序列上搞,简单模拟 #include<stdio.h> #include<iostream> #include<string.h> #include<set> #include<vector> #include<map> #include<math.h&

hdu 3333 树状数组+离线处理

http://acm.hdu.edu.cn/showproblem.php?pid=3333 不错的题,想了很久不知道怎么处理,而且答案没看懂,然后找个例子模拟下别人的代码马上懂了---以后看不懂的话就拿个例子模拟下别人的代码 举个例子:1 3 3 5 3 5 查询 a, 2 4 b, 2 5 最初是这么想的:对于a查询,倘若把第二个数第三个数变成1个3,那么到b查询,又出现了两个3,再做处理似乎还是O(n),而且如果先出现2,5查询,后出现2,4查询,那么还需要把删除的数补回来.....o(╯

13杭州区域赛现场赛Rabbit Kingdom(树状数组+离线)

题意:给你一个长度数列,再给你m个询问(一个区间),问你在这个区间里面有多少个数与其他的数都互质. 解题思路:你看这种类型的题目都可以肯定这是 离线+树状数组(线段树).主要就是他的更新信息.这里我的处理是先把1-200000(每个数的范围)数里面所有的质因子求出来.然后从后往前遍历数组.会出现以下几种情况 1.a[k]的质因子在后面出现过而[更新标记] 和[被更新标记] 都为假 2.a[k]的质因子在后面出现过的那个位置 I   [更新标记]为 真 . 3.a[k]的质因子在后面出现过且那个位

HDU 3333 Turing Tree 树状数组 离线查询

题意: 给你一个数列,然后有n个查询,问你给定区间中不同数字的和是多少. 思路还是比较难想的,起码对于蒟蒻我来说. 将区间按照先右端点,后左端点从小到大排序之后,对于每个查询,我只要维护每个数字出现的最后一次就可以了(这个结论稍微想一下就可以证明是正确的). 然后就是简单的点更新,区间求和问题了- #include <cstdio> #include <cstring> #include <iostream> #include <map> #include