Codeforces Round #365 (Div. 2)-D Mishka and Interesting sum(树状数组)
题目链接:http://codeforces.com/contest/703/problem/D
思路:看了神犇的代码写的...
偶数个相同的数异或结果为0,所以区间ans[l , r]=区间[l , r]每个数相异或^区间[l , r]出现过的数相异或。如数组1,2,1,3,3,2,3,则ans[1 , 7]=(1^2^1^3^3^2^3)^(1^2^3)
前半部分可以处理出前缀异或,后半部分先对询问按r进行排序,处理过程中相同的数只保留最后一个。
#include<bits/stdc++.h> #define lowbit(x) x&(-x) using namespace std; typedef long long ll; const int N=1e6+3; int n,a[N],prefix[N],last[N],c[N],ans[N]; struct node { int l,r,id; }q[N]; map<int,int> temp; bool cmp(node a,node b) { return a.r<b.r; } void update(int pos,int num) { while(pos<=n) { c[pos]^=num; pos+=lowbit(pos); } } int query(int pos) { int res=0; while(pos) { res^=c[pos]; pos-=lowbit(pos); } return res; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",a+i); prefix[i]=prefix[i-1]^a[i]; last[i]=temp[a[i]]; temp[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+m+1,cmp); for(int i=1,cur=1;i<=m;i++) { while(cur<=q[i].r) { if(last[cur]) update(last[cur],a[cur]); update(cur,a[cur]); cur++; } ans[q[i].id]=query(q[i].r)^query(q[i].l-1)^prefix[q[i].r]^prefix[q[i].l-1]; } for(int i=1;i<=m;i++) printf("%d\n",ans[i]); return 0; }