CF703D Mishka and Interesting sum

链接:Miku

-----------------------------------

这道题虽说是要偶数个数的数的异或和,但是这就是等于区间奇数个数的数的异或和异或上数的种类的异或和

-------------------------------------

然后奇数这部分可以用前缀异或和来解决,至于种类的问题,就和HH的项链方法一样了

--------------------------------------

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
int n,m;
int a[1000005];
struct qu{
    int l;
    int r;
    int num;
}qj[1000005];
map<int,int>fl;
bool cmp(qu x,qu y){
    return x.r<y.r;
}
int tree[1000005];
int ans[1000005];
int sum1[1000005];
int lowbit(int x){
    return x&-x;
}
void add(int x,int k){
    while(x<=n){
        tree[x]^=k;
        x+=lowbit(x);
    }
    return ;
}
int sum(int x){
    int ans=0;
    while(x){
        ans^=tree[x];
        x-=lowbit(x);
    }
    return ans;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i){
        scanf("%d",&a[i]);
        sum1[i]=sum1[i-1]^a[i];
    }
    scanf("%d",&m);
    for(int i=1;i<=m;++i){
        scanf("%d%d",&qj[i].l,&qj[i].r);
        qj[i].num=i;
    }
    sort(qj+1,qj+m+1,cmp);
    int r = 1;
    for(int i=1;i<=m;++i){
        while (r <= qj[i].r){
            add(r, a[r]);//我们记录的是异或和 
            if (fl.find(a[r]) != fl.end()){//这个题的数据很大,所以要用map 
                add(fl[a[r]], a[r]);//逆运算还是异或 
            }
            fl[a[r]] = r;
            r++;
        }
        ans[qj[i].num] =sum1[qj[i].r]^sum1[qj[i].l-1]^sum(qj[i].r) ^ sum(qj[i].l - 1);
    }
    for (int i = 1; i <= m; i++) printf("%d\n", ans[i]);
    return 0;
}
Ac

 

posted @ 2020-02-15 18:57  Simex  阅读(159)  评论(0编辑  收藏  举报