CF703D. Mishka and Interesting sum

来源:互联网 发布:暴风vr电视直播软件 编辑:程序博客网 时间:2024/06/11 09:42

题目大意:给一个长度为n的序列,m次询问,询问为区间中所有出现了偶数次的数的异或和。

题解:由于区间的异或和剩下的是出现奇数次的数,每次询问的答案即为 x^y  x=区间内所有出现了的数的异或和 y=区间内出现了奇数次的数的异或和.如果在线询问的话x不好维护。所以离线处理,如果这个数出现过就抹去之前出现的点,保证每个数只出现一次。

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cmath>#include <map>#include <vector>using namespace std;#define maxn 4001000#define pb push_back#define mp make_pair#define ft first#define sd second#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1#define getmid int mid=(l+r)>>1map<int,int>myp;vector<pair<int,int> >g[maxn];int ans[maxn];int siz,n,pre[maxn],xorsum[maxn],a[maxn],m;void pushup(int rt){    xorsum[rt]=xorsum[rt<<1]^xorsum[rt<<1|1];}int query(int l,int r,int rt,int st,int ed){    if(st<=l&&r<=ed)    {        return xorsum[rt];    }    getmid;    int t1=0,t2=0;    if(st<=mid)        t1=query(lson,st,ed);    if(ed>mid)        t2=query(rson,st,ed);    return t1^t2;}void update(int l,int r,int rt,int pos,int f){    if(l==r)    {        xorsum[rt]^=f;        return;    }    getmid;    if(pos<=mid) update(lson,pos,f);    else update(rson,pos,f);    pushup(rt);}int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++)    {        scanf("%d",&a[i]);        pre[i]=pre[i-1]^a[i];    }    int l,r;    scanf("%d",&m);    for(int i=1;i<=m;i++)    {        scanf("%d%d",&l,&r);        g[r].pb(mp(l,i));    }    int ll,rr;    for(int i=1;i<=n;i++)    {        if(myp[a[i]]!=0) update(1,n,1,myp[a[i]],a[i]);        update(1,n,1,i,a[i]);        myp[a[i]]=i;        rr=i;        for(int j=0;j<g[i].size();j++)        {            ll=g[i][j].ft;            ans[g[i][j].sd]=pre[rr]^pre[ll-1]^query(1,n,1,ll,rr);        }    }    for(int i=1;i<=m;i++)    {        printf("%d\n",ans[i]);    }    return 0;}


0 0
原创粉丝点击