Codeforces Round #365 (Div. 2) D.Mishka and Interesting sum

题目链接:传送门

题目大意:给n个数,m次询问,每次询问区间 l,r 内出现偶数次数的异或和

题目思路:前缀和+离线处理+树状数组

     首先可以知道, l,r 内出现奇数次的数的和,就是把 l,r内所有数异或起来就是答案,那么出现偶数次的数就可以

     先求出区间 l,r 内有多少不同的数,将这些数异或起来,再异或上区间内出现奇数次的数的异或和就是答案。(出现偶数次的数异或后为0,奇数次的数异或后是本身

       然后离线处理询问,对询问按右端点 sort,因为树状数组保存的是数出现的最后位置。离线处理询问后便于数组的更新以及答案的更新。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <cctype>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <climits>
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define fi first
#define se second
#define ping(x,y) ((x-y)*(x-y))
#define mst(x,y) memset(x,y,sizeof(x))
#define mcp(x,y) memcpy(x,y,sizeof(y))
using namespace std;
#define gamma 0.5772156649015328606065120
#define MOD 1000000007
#define inf 0x3f3f3f3f
#define N 1000005
#define maxn 100005
typedef pair<int,int> PII;
typedef long long LL;

int n,m,flag;
int sum[N],tree[N],a[N];
struct Node{
    int l,r;
    int v,id;
    bool operator<(const Node&a)const{
        return r<a.r;
    }
}node[N];
map<int,int>M;
bool cmp(const Node&a,const Node&b){return a.id<b.id;}
void add(int i,int v){for(;i<=n;i+=(i&-i))tree[i]^=v;}
int getsum(int i){int res=0;for(;i;i-=(i&-i))res^=tree[i];return res;}
int main(){
    int i,j,group,temp;
    //freopen("in.txt","r",stdin);
    scanf("%d",&n);
    for(i=1;i<=n;++i){
        scanf("%d",&a[i]);
        sum[i]=sum[i-1]^a[i];
    }
    scanf("%d",&m);
    for(i=1;i<=m;++i){
        scanf("%d%d",&node[i].l,&node[i].r);
        node[i].id=i;
    }
    sort(node+1,node+m+1);
    j=1;
    for(i=1;i<=n;++i){
        int &t=M[a[i]];
        if(t){
            add(t,a[i]);
        }
        t=i;
        add(t,a[i]);
        while(j<=m&&node[j].r==i){
            int l=node[j].l-1;
            int r=node[j].r;
            node[j].v=getsum(r)^getsum(l)^sum[r]^sum[l];
            ++j;
        }
    }
    sort(node+1,node+m+1,cmp);
    for(i=1;i<=m;++i)printf("%d\n",node[i].v);
    return 0;
}

 

posted @ 2016-08-06 16:04  Kurokey  阅读(165)  评论(0编辑  收藏  举报