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
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
Each query is processed in the following way:
- Two integerslandr(1 ≤l≤r≤n) are specified — bounds of query segment.
- Integers, presented in array segment [l,r] (in sequence of integersal,al+ 1, ...,ar) even number of times, are written down.
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
Examples
input
3
3 7 8
1
1 3
output
0
input
7
1 2 1 3 3 2 3
5
4 7
4 5
1 3
1 7
1 5
output
0
3
1
3
2
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
.
题意:给你一个数组,问你在区间为【L,R】上出现次数为偶数的数的异或和是多少。
题解:我们可以先预处理一下全部数的异或和。如果求出现次数是奇数的数的异或和,就是简单的前缀和嘛。题目要
求是出现次数是偶数的异或和,那我们可以在异或一遍。因为一个数异或奇数次是本身,一个数异或偶数次就是0,
那我们可以将全部数的异或和再和区间中相关的数再异或一遍,得出的就是答案了。在区间询问异或时可以用树状数
组 或者 线段树 不断维护更新一下。复杂度(logN)
AC代码:
#include<bits/stdc++.h>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<stack>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int read()
{
int v = 0, f = 1;
char c =getchar();
while( c < 48 || 57 < c ){
if(c=='-') f = -1;
c = getchar();
}
while(48 <= c && c <= 57)
v = v*10+c-48, c = getchar();
return v*f;
}
const int maxn = 1e6+7;
int a[maxn],sum[maxn],pre[maxn],c[maxn],ans[maxn];
map<int,int>vis;
struct Node
{
int l,r,id;
}q[maxn];
int lowbit(int x){
return x & (-x);
}
void update(int i,int num)
{
while(i<=maxn){
c[i]^=num;
i+=lowbit(i);
}
}
int query(int i)
{
int ans = 0;
while(i)
{
ans^=c[i];
i-=lowbit(i);
}
return ans;
}
bool cmp(Node a, Node b)
{
if(a.r==b.r) return a.l<b.l;
return a.r<b.r;
}
int main()
{
int n;
scanf("%d",&n);
for(int i =1; i<=n; i++)
{
scanf("%d",&a[i]);
sum[i] = sum[i-1]^a[i];
pre[i] = vis[a[i]];
vis[a[i]] = i;
}
int m;
scanf("%d",&m);
for(int i= 1; i <= m; i++){
scanf("%d%d",&q[i].l,&q[i].r), q[i].id = i;
}
sort(q+1, q+1+m, cmp);
for(int i = 1, r=1; i<=m; i++ ){
while(r <= q[i].r){
if(pre[r])
update(pre[r],a[r]);
update(r,a[r]);
r++;
}
//printf("%d",query(q[i].r) ^ query(q[i].l - 1));
ans[q[i].id] = query(q[i].r) ^ query(q[i].l - 1) ^ sum[q[i].r] ^ sum[q[i].l-1];
}
for(int i = 1; i<=m; i++)
{
printf("%d\n",ans[i]);
}
return 0;
}