Infiniti

   :: 首页  :: 新随笔  ::  ::  :: 管理

 CodeForces - 617E 

给n个数, m个询问, 每次询问问你[l, r]区间内有多少对(i, j), 使得a[i]^a[i+1]^......^a[j]结果为k。(注意 i ! =  j)
维护一个前缀异或值就可以了。要注意的是 区间[l, r], 我们需要将pre[l-1]......pre[r]都加进去, pre[l-1]不能少。

#include<bits/stdc++.h>
using namespace std;
#define maxn 1234567
#define ll long long
ll s[1<<22],n,m,k,col[maxn],B,sum,ans[maxn],pre[maxn],l,r;
struct node
{
    int l,r,id;
    bool operator<(const node &b)const
    {
        return l/B==b.l/B?r<b.r:l<b.l;
    }
} a[maxn];
void del(int x)
{
    s[pre[x]]--;
    sum-=s[k^pre[x]];
}
void add(int x)
{
    sum+=s[k^pre[x]];
    s[pre[x]]++;
}
int main()
{
    r=-1;
    scanf("%lld%lld%lld",&n,&m,&k);
    for(int i=1; i<=n; i++)
    {
        scanf("%lld",&col[i]);
        pre[i]=pre[i-1]^col[i];
    }
    B=sqrt(n);
    for(int i=0; i<m; i++)
    {
        scanf("%d%d",&a[i].l,&a[i].r);
        a[i].id=i;
        a[i].l--;
    }
    sort(a,a+m);
    for(int i=0; i<m; i++)
    {
        while(l<a[i].l)
            del(l++);
        while(r>a[i].r)
            del(r--);
        while(l>a[i].l)
            add(--l);
        while(r<a[i].r)
            add(++r);
        ans[a[i].id]=sum;
    }
    for(int i=0; i<m; i++)printf("%lld\n",ans[i]);
    return 0;
}

  

posted on 2019-01-13 00:03  自由缚  阅读(133)  评论(0编辑  收藏  举报