这个题首先处理异或前缀和
a[i] = a[1] ^ a[2] ^ a[3] … ^a[i]
如果a[i] ^ a[j] = k
那么 a[i] = k^a[j]
a[j] = k^a[i]
交换异或顺序不改变结果!
然后按照莫队的板子搞就行
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#define b belong
using namespace std;
int n,m,k;
long long ans;
int a[100100],belong[100100],cnt[5001000];
struct Node
{
int l,r,id;
long long ans;
}node[100100];
//左端点按照块号排序,右端点按照大小排序
bool cmp1(Node &q1,Node &q2)
{
if(b[q1.l] != b[q2.l]) return b[q1.l] < b[q2.l];
if(b[q1.l] & 1) return q1.r < q2.r;
return q1.r > q2.r;
}
bool cmp2(Node &q1,Node &q2)
{
return q1.id < q2.id;
}
void add(int pos)
{
ans += cnt[a[pos]^k];
cnt[a[pos]]++;
}
void del(int pos)
{
cnt[a[pos]]--;
ans -= cnt[a[pos]^k];
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
int num = sqrt(n);
int length = n/num;
for(int i = 1; i <= n; i++)
belong[i] = (i-1)/length + 1;
for(int i = 1; i <=n; i++)
scanf("%d",&a[i]),a[i] ^= a[i-1];
for(int i = 1;i <= m; i++)
{
scanf("%d%d",&node[i].l,&node[i].r);
node[i].l--;//左区间减一
node[i].id = i ;
}
/**
* 莫队核心代码
*/
sort(node+1,node+m+1,cmp1);
int l = 1,r = 0;
for(int i = 1; i <= m; i++)
{
while(l < node[i].l) del(l++);
while(l > node[i].l) add(--l);
while(r < node[i].r) add(++r);
while(r > node[i].r) del(r--);
node[i].ans = ans;
}
sort(node+1,node+m+1,cmp2);
for(int i = 1;i <= m; i++)
printf("%lld\n",node[i].ans);
return 0;
}