Portal: http://codeforces.com/contest/617/problem/E
The meaning of the question:
Given a series of numbers, for each query interval, calculate how many sub-intervals are XORed as k.
Idea:
You can preprocess the XOR prefix first, the XOR value of an interval [L, R] = sum[R]^sum[L-1];
if the current interval is [a, b], add a right endpoint b+ 1, then the contribution of this b+1 is how many sum[x]=sum[b+1]^k in the [a,b] interval,
then we can record num[sum[x]] each time, that is, num[sum [b+1]^k], and record num[sum[b+1]]++, the same goes for the left interval.
Then we can use the Mo team algorithm.
#include <iostream> #include <cstdio> #include <algorithm> typedef long long ll; using namespace std; const int maxn = 1<<20; ll a[maxn]; ll sum = 0, ans[maxn]; int k,B = 233,cnt[maxn]; #define bel(x) ((x-1)/B +1) struct node{ int id,l,r; }q[maxn]; bool cmp (node a, node b) { if(bel(a.l) == bel(b.l)) return a.r < b.r; return bel(a.l) < bel(b.l); } void add(int x) { sum += cnt[x^ k]; cnt[x] ++; } void del (int x) { cnt[x] --; sum = cnt[x^ k]; } int main(){ int n,m; scanf("%d%d%d",&n,&m,&k); for(int i=1; i<=n; i++) { scanf("%I64d",&a[i]); a[i] ^= a[i-1]; } for(int i = 1; i <= m; i++) { scanf("%d%d",&q[i].l,&q[i].r); q[i].id = i; } sort(q+1, q+m+1, cmp); ll ql = 1,qr = 0; cnt[0] = 1; for(int i=1; i<=m; i++) { while(ql < q[i].l) del(a[ql-1]),ql++; while(ql > q[i].l) ql--,add(a[ql-1]); while(qr > q[i].r) del (a[qr--]); while(qr < q[i].r) add (a[++qr]); ans[q[i].id] = sum; } for(int i=1; i<=m; i++) printf("%I64d\n",ans[i]); return 0; }