Codeforces617E XOR and Favorite Number(分块 异或)
Bob has a favorite number k and ai of length n. Now he asks you to answer m queries. Each query is given by a pair li and ri and asks you to count the number of pairs of integers i and j, such that l ≤ i ≤ j ≤ r and the xor of the numbers ai, ai + 1, ..., ajis equal to k.
Input
The first line of the input contains integers n, m and k (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 integers ai (0 ≤ ai ≤ 1 000 000) — Bob's array.
Then m lines follow. The i-th line contains integers li and ri (1 ≤ li ≤ ri ≤ n) — the parameters of the i-th query.
Output
Print m lines, answer the queries in the order they appear in the input.
Example
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
Note
In the first sample the suitable pairs of i and j 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.
题意:
给定数列a[],和m个询问 Q(L,R),回答每个询问中有多少对(L<=i<=j<=R) ,使得异或为k。
异或转化为前缀和处理。然后就差不多交给分块处理了。
离线处理里比较好理解的一种,高中就会了,注意这里不多BB了。
#include<cstdio> #include<cstdlib> #include<iostream> #include<algorithm> #include<cstring> #include<cmath> #define ll long long using namespace std; const int maxn=100010; int a[maxn],pre[maxn],num[1<<20],n,m,k,sqrtn; struct Query{ int id,l,r; ll ans; }q[maxn]; bool cmp(const Query a,const Query b) { if(a.l/sqrtn==b.l/sqrtn) return a.r<b.r; return a.l<b.l; } bool cmp2(const Query a,const Query b) { return a.id<b.id; } int main() { scanf("%d%d%d",&n,&m,&k); sqrtn=(int)sqrt(n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); pre[i]=pre[i-1]^a[i]; } for(int i=0;i<m;i++){ scanf("%d%d",&q[i].l,&q[i].r); q[i].id=i; } sort(q,q+m,cmp); int l=1,r=1; num[pre[1]]++;num[0]++; ll cur=(a[1]==k?1:0); for(int i=0;i<m;i++) { while(r<q[i].r){ cur+=num[pre[r+1]^k]; r++; num[pre[r]]++; } while(l<q[i].l){ num[pre[l-1]]--; cur-=num[pre[l-1]^k]; l++; } while(l>q[i].l){ cur+=num[pre[l-2]^k]; num[pre[l-2]]++; l--; } while(r>q[i].r){ num[pre[r]]--; cur-=num[pre[r]^k]; r--; } q[i].ans=cur; } sort(q,q+m,cmp2); for(int i=0;i<m;i++) printf("%lld\n",q[i].ans); return 0; }