题意
给定序列 (a),非负整数 (k),(m) 次询问:([l,r]) 内有多少子区间的异或和为 (k)。(n,mleq 10^5)。
题解
莫队。用一个桶记录当前区间内值为 (i) 的数的数量,移动指针时加减对应的数即可。
#include<bits/stdc++.h>
using namespace std;
int getint(){
int ans=0;
char c=getchar();
while(c<'0'||c>'9')c=getchar();
while(c>='0'&&c<='9'){
ans=ans*10+c-'0';
c=getchar();
}
return ans;
}
const int N=1e5+10,M=1<<20;
#define ll long long
struct query{
int l,r,id;
};
query q[N];
int a[N],c[M];
int n,m,k,b;
bool cmp(const query &x,const query &y){
if(x.l/b!=y.l/b)return x.l/b<y.l/b;
return (x.r/b<y.r/b);
}
ll ans[N];
int main(){
n=getint(),m=getint(),k=getint();
b=sqrt(n)+1;
for(int i=1;i<=n;i++)a[i]=getint()^a[i-1];
for(int i=0;i<m;i++)
q[i].l=getint()-1,q[i].r=getint(),q[i].id=i;
sort(q,q+m,cmp);
int l=1,r=0;
ll ans=0;
for(int i=0;i<m;i++){
while(r>q[i].r){
c[a[r]]--;
ans-=c[a[r]^k];
--r;
}
while(r<q[i].r){
++r;
ans+=c[a[r]^k];
c[a[r]]++;
}
while(l<q[i].l){
c[a[l]]--;
ans-=c[a[l]^k];
++l;
}
while(l>q[i].l){
--l;
ans+=c[a[l]^k];
c[a[l]]++;
}
::ans[q[i].id]=ans;
}
for(int i=0;i<m;i++)printf("%lld
",::ans[i]);
return 0;
}