BZOJ 5301: [Cqoi2018]异或序列 莫队+桶
开一个桶记录一下前缀异或值的个数即可.
注意要把询问从 $(l,r)$ 变成 $(l-1,r)$,这样做的话会方便很多.
code:
#include <cstdio>
#include <cmath>
#include <algorithm>
#define N 1000005
#define ll long long
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
ll ans=0ll;
int n,m,k,B,K;
int a[N],h[N],cnt[N];
ll answer[N];
struct node
{
int l,r,id;
node(int l=0,int r=0,int id=0):l(l),r(r),id(id){}
}q[N];
bool cmp(node x,node y)
{
return x.l/B==y.l/B?x.r<y.r:x.l<y.l;
}
void del(int x)
{
ans-=cnt[K^x];
--cnt[x];
}
void add(int x)
{
++cnt[x];
ans+=cnt[K^x];
}
int main()
{
// setIO("input");
int i,j,l=2,r=1;
scanf("%d%d%d",&n,&m,&K),B=sqrt(n);
for(i=1;i<=n;++i) scanf("%d",&a[i]),h[i]=h[i-1]^a[i];
for(i=1;i<=m;++i) scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i,--q[i].l;
sort(q+1,q+1+m,cmp);
for(i=1;i<=m;++i)
{
while(l>q[i].l) add(h[--l]);
while(r<q[i].r) add(h[++r]);
while(l<q[i].l) del(h[l++]);
while(r>q[i].r) del(h[r--]);
answer[q[i].id]=ans;
}
for(i=1;i<=m;++i) printf("%lld\n",answer[i]);
return 0;
}

浙公网安备 33010602011771号