http://codeforces.com/problemset/problem/617/E
题意:
给出n个数,每次查询一个区间 ,求内部有多少个子区间,其异或值为 。
解析:
采取莫队的做法,假设当前 ,变为 ,那么得到的区间为以 为左端点,右端点 ,区间异或为 。
前缀异或的思想:
假设 为 ,那么我们相当于要找多少个以1为左端点,右端点 ,异或值为 的,而我们开一个数组记录异或值为 的左端点为1,右端点落在当前区间内的段。
代码:
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define LL long long
const int maxn=1e6+9;
int n,m,k;
int a[maxn];
int Size;
int Id(int idx){
return (idx-1)/Size+1;
}
struct node{
int l,r,id;
bool operator<(const node &A)const{
if(Id(l)==Id(A.l))return r<A.r;
return l<A.l;
}
}q[maxn];
LL Ans[maxn];
int xorP[maxn],xorB[maxn],ctP[maxn<<1],ctB[maxn<<1];
int main(){
scanf("%d%d%d",&n,&m,&k);
rep(i,1,n)scanf("%d",a+i);
rep(i,1,n)xorP[i]=a[i]^xorP[i-1];
per(i,n,1)xorB[i]=a[i]^xorB[i+1];
Size=sqrt(n);
rep(i,1,m){
scanf("%d%d",&q[i].l,&q[i].r);
q[i].id=i;
}
sort(q+1,q+1+m);
int l=1,r=0;
LL ans=0;
rep(i,1,m){
while(r<q[i].r){
ctB[xorB[r+1]]++;
ctP[xorP[r+1]]++;
int base=xorB[r+2];
ans+=ctB[k^base];
r++;
}
while(l>q[i].l){
ctB[xorB[l-1]]++;
ctP[xorP[l-1]]++;
int base=xorP[l-2];
ans+=ctP[k^base];
l--;
}
while(r>q[i].r){
int base=xorB[r+1];
ans-=ctB[k^base];
ctB[xorB[r]]--;
ctP[xorP[r]]--;
r--;
}
while(l<q[i].l){
int base=xorP[l-1];
ans-=ctP[k^base];
ctB[xorB[l]]--;
ctP[xorP[l]]--;
l++;
}
Ans[q[i].id]=ans;
}
rep(i,1,m)printf("%lld\n",Ans[i]);
}