Bob has a favorite number k andai of lengthn. Now he asks you to answerm queries. Each query is given by a pairli andri and asks you to count the number of pairs of integersi andj, such thatl ≤ i ≤ j ≤ r and the xor of the numbers ai, ai + 1, ..., aj is equal to k.
The first line of the input contains integers n,m andk (1 ≤ n, m ≤ 100 000,0 ≤ k ≤ 1 000 000) — the length of the array, the number of queries and Bob's favorite number respectively.
The second line contains n integersai (0 ≤ ai ≤ 1 000 000) — Bob's array.
Then m lines follow. Thei-th line contains integersli andri (1 ≤ li ≤ ri ≤ n) — the parameters of the i-th query.
Print m lines, answer the queries in the order they appear in the input.
6 2 3
1 2 1 1 0 3
1 6
3 5
7
0
5 3 1
1 1 1 1 1
1 5
2 4
1 3
9
4
4
In the first sample the suitable pairs of i andj for the first query are: (1,2), (1,4), (1,5), (2,3), (3,6), (5,6), (6,6). Not a single of these pairs is suitable for the second query.
In the second sample xor equals 1 for all subarrays of an odd length.
题意:给你n个数,然后询问m次,每次询问一个区间[l,r],问你在这个区间内有多少子区间,使得子区间内所有值的亦或值为k
分析:
莫队算法:离线处理没有修改的区间查询,当你知道[L,R]的答案后,可以在O(1)的时间内知道[L-1,R],[L+1,R],[L,R-1],[L,R+1]的答案时,就可以使用莫队算法。
用sum[]数组记录前缀亦或值,如果一个区间[l,r]的所有值的亦或值为k,那么sum[r]^sum[l-1]==k,也就是sum[r]^k==sum[l-1]
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define block 320
#define maxn 100010
#define LL __int64
int sum[maxn];
int n,m,k;
struct node
{
int l,r,unit,id;
node(){}
node(int l,int r,int unit,int id): l(l),r(r),unit(unit),id(id) {}
inline bool operator < (const node &x) const
{
if(unit==x.unit) return r<x.r;
return unit<x.unit;
}
}E[maxn];
LL ans[maxn];
LL cnt[maxn*20];
int l,r;
LL res;
void add(int x)
{
res+=cnt[x^k];
cnt[x]++;
}
void del(int x)
{
cnt[x]--;
res-=cnt[x^k];
}
int main()
{
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
sum[0]=0;
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
sum[i]=sum[i-1]^x;
}
for(int i=1;i<=m;i++)
{
scanf("%d%d",&l,&r);
l--;
E[i]=node(l,r,l/block,i);
}
sort(E+1,E+m+1);
memset(cnt,0,sizeof(cnt));
cnt[0]=1;
l=0,r=0,res=0;
for(int i=1;i<=m;i++)
{
while(r<E[i].r)
{
r++;
add(sum[r]);
}
while(r>E[i].r)
{
del(sum[r]);
r--;
}
while(l<E[i].l)
{
del(sum[l]);
l++;
}
while(l>E[i].l)
{
l--;
add(sum[l]);
}
ans[E[i].id]=res;
}
for(int i=1;i<=m;i++) printf("%I64d\n",ans[i]);
}
return 0;
}