codeforces CF703D Mishka and Interesting sum 树状数组


题意:给出一个有n个元素的数组a,1<= a[i] <= 10^9,m次询问,区间[l,r]见出现了偶次的数的异或值,没有出现过的数不能异或。

分析:首先一开始的思路是用区间出现过的数的异或值异或出现过奇数次的数的异或值。
那么我们预处理出一个前缀异或值,设为sum[i],那么区间[l,r]内出现过奇数次的数的异或值就是sum[r]^sum[l-1]。
那么现在就要求该区间内出现过的数的异或值。
而这东西可以用一个树状数组来维护。
维护的方式有点像维护区间出现过的数的数量。
先预处理出一个数组last[i]表示a[i]上一次出现的位置。
那么我们每次往树状数组里面加入一个数a[i]之前,就要先把last[i]位置上的数删除掉。然后就把右端点为i的区间处理掉就好了。
举个例子,对于序列1 2 1 2
更新结果依次为
1 0 0 0
1 2 0 0
0 2 1 0
0 0 1 2

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define N 1000005
using namespace std;

int n,m,c[N],a[N],sum[N],last[N];
struct data{int l,r,ans,id;}q[N];
struct hehe{int a,id;}b[N];

bool cmp(data a,data b)
{
    return a.r<b.r;
}

int lowbit(int x)
{
    return x&(-x);
}

void ins(int x,int y)
{
    if (!x) return;
    while (x<=n)
    {
        c[x]^=y;
        x+=lowbit(x);
    }
}

int find(int x)
{
    if (!x) return 0;
    int s=0;
    while (x)
    {
        s^=c[x];
        x-=lowbit(x);
    }
    return s;
}

bool cmp1(data a,data b)
{
    return a.id<b.id;
}

bool cmp2(hehe a,hehe b)
{
    return (a.a<b.a||a.a==b.a&&a.id<b.id);
}

int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        b[i].a=a[i];b[i].id=i;
        sum[i]=sum[i-1]^a[i];
    }
    sort(b+1,b+n+1,cmp2);
    for (int i=2;i<=n;i++)
        if (b[i].a==b[i-1].a) last[b[i].id]=b[i-1].id;
    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);
    int point=1;
    for (int i=1;i<=n;i++)
    {
        if (last[i]) ins(last[i],a[i]);
        ins(i,a[i]);
        while (q[point].r==i)
        {
            q[point].ans=find(q[point].r)^find(q[point].l-1)^sum[i]^sum[q[point].l-1];
            point++;
        }
        if (point>m) break;
    }
    sort(q+1,q+m+1,cmp1);
    for (int i=1;i<=m;i++)
        printf("%d\n",q[i].ans);
    return 0;
}

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
© 2014-2018 ITdaan.com 粤ICP备14056181号