题意
有n个数和m次查询,每次查询区间[l, r]问满足ai ^ ai+1 ^ … ^ aj == k的(i, j) (l <= i <= j <= r)有多少对。
题解
离线 莫队算法
代码
#include<bits/stdc++.h>
using namespace std;
typedef double db;
typedef long long ll;
typedef unsigned long long ull;
const int nmax = 1e6+1e5;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const ull p = 67;
const ull MOD = 1610612741;
ll n,m,k,sz,tot;
ll a[nmax],prefix[nmax],ans[nmax],cnt[nmax];
int belong[nmax];
struct node{
int l,r,id;
}Q[nmax];
bool cmp(node a, node b){
if(belong[a.l] != belong[b.l]) return belong[a.l] < belong[b.l];
else return a.r < b.r;
}
void modify(int val, int tag){
if(tag > 0) tot += cnt[k^val] ,cnt[val] ++;
else cnt[val] --, tot -= (ll) cnt[k^val];
}
int main(){
scanf("%I64d %I64d %I64d",&n,&m,&k);
sz = (int) sqrt(n);
for(int i = 1;i<=n;++i) scanf("%I64d",&a[i]),a[i] ^= a[i-1],belong[i] = (i-1) / sz + 1;
for(int i = 1;i<=m;++i) scanf("%d %d",&Q[i].l,&Q[i].r), Q[i].id = i,Q[i].l --;
sort(Q+1,Q+1+m,cmp);
int l = 1, r = 0;
for(int i = 1;i<=m;++i){
while(l < Q[i].l) modify(a[l++],-1);
while(l > Q[i].l) modify(a[--l],1);
while(r < Q[i].r) modify(a[++r],1);
while(r > Q[i].r) modify(a[r--],-1);
ans[Q[i].id] = tot;
}
for(int i = 1;i<=m;++i) printf("%I64d\n",ans[i]);
return 0;
}