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;
}

 



 

posted on 2016-08-18 19:03  polarday  阅读(130)  评论(0编辑  收藏  举报

导航