[CF617E]XOR and Favorite Number

来源:互联网 发布:温十如何解除网络禁用 编辑:程序博客网 时间:2024/06/05 02:37

617E:XOR and Favorite Number

题意简述

给出一个n个元素的数列aq个询问,每个询问查询有多少lijr,aiai+1...aj1aj=k

数据范围

1n,q105
1ai,k106
1lirin

思路

莫队。
先把求出前缀异或和,这样任意区间都可以通过两个前缀异或得到。
莫队的每个修改都可以在O(1)的时间内处理,即查询xk出现了多少次。
总时间复杂度O(nn)

代码

#include <cstdio>#include <cmath>#include <algorithm>using namespace std;int n,q,k,lim;int seq[100010],cnt[1100010];long long tot;long long ans[100010];struct ask{    int l,r,id;    bool operator < (const ask &n1) const    {        return l/lim==n1.l/lim ? r<n1.r : l/lim<n1.l/lim;    }}a[100010];int main(){    scanf("%d%d%d",&n,&q,&k);    lim=int(sqrt(n));    for (int i=1;i<=n;i++)        scanf("%d",&seq[i]);    for (int i=1;i<=n;i++)        seq[i]^=seq[i-1];    for (int i=1;i<=q;i++)    {        scanf("%d%d",&a[i].l,&a[i].r);        a[i].id=i;    }    sort(a+1,a+q+1);    int l=a[1].l,r=a[1].l;    cnt[seq[l-1]]++;    tot=cnt[k^seq[a[1].l]];    cnt[seq[l]]++;    for (int i=1;i<=q;i++)    {        while (l<a[i].l)        {            cnt[seq[l-1]]--;            tot-=cnt[k^seq[l-1]];            l++;        }        while (l>a[i].l)        {            l--;            tot+=cnt[k^seq[l-1]];            cnt[seq[l-1]]++;        }        while (r<a[i].r)        {            r++;            tot+=cnt[k^seq[r]];            cnt[seq[r]]++;        }        while (r>a[i].r)        {            cnt[seq[r]]--;            tot-=cnt[k^seq[r]];            r--;        }        ans[a[i].id]=tot;    }    for (int i=1;i<=q;i++)        printf("%I64d\n",ans[i]);    return 0;}
0 0
原创粉丝点击