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

时间:2022-03-29 12:24:56

题目链接: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;
}