很早就听说过莫队这个人了,这次终于开始接触他的算法了。
所谓莫队算法,这题思路就是把n次查询按 L 的大小分成 sqrt(n) 块,再在每块中对 R 进行从小到大排序, 然后分块处理, L 转移的复杂度就由 n 减小为 sqrt(n)了。
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<string.h>
#include<math.h>
#define eps 1e-9
#define nn 1000005
#define INF 0x7FFFFFFF
#define pi acos(-1)
#define e 2.718281828459045
#define mod 522462628
#define LL __int64
using namespace std;
/*-----------------------------never more!---------------------------*/
/*
_______________#########_______________________
______________############_____________________
______________#############____________________
_____________##__###########___________________
____________###__######_#####__________________
____________###_#######___####_________________
___________###__##########_####________________
__________####__###########_####_______________
________#####___###########__#####_____________
_______######___###_########___#####___________
_______#####___###___########___######_________
______######___###__###########___######_______
_____######___####_##############__######______
____#######__#####################_#######_____
____#######__##############################____
___#######__######_#################_#######___
___#######__######_######_#########___######___
___#######____##__######___######_____######___
___#######________######____#####_____#####____
____######________#####_____#####_____####_____
_____#####________####______#####_____###______
______#####______;###________###______#________
________##_______####________####______________
╢п╧ы╢м╦ё ╟ынч╫Ш╪и
*/
LL cnt[4400000],pre[1000005];
struct Query
{
LL l,r,id;
bool operator < (const Query &a) const
{
return a.r>r;
}
}q[1000005];
LL ans[1000005];
int main()
{
LL n,m,k;
scanf("%I64d%I64d%I64d",&n,&m,&k);
LL i,j,block=sqrt(n)+2;
pre[0]=0;
for(i=1;i<=n;i++)
{
LL x;
scanf("%I64d",&x);
pre[i]=pre[i-1]^x;
}
vector< vector<Query> > v(block,vector<Query>());
for(i=1;i<=m;i++)
{
scanf("%I64d%I64d",&q[i].l,&q[i].r);
q[i].l--;
q[i].id=i;
LL t=q[i].l/block;
v[t].push_back(q[i]);
}
LL size=v.size();
//memset(cnt,0,sizeof(cnt));
for(i=0;i<size;i++)
{
sort(v[i].begin(),v[i].end());
LL ss=v[i].size();
if(ss==0)
continue;
/*for(j=0;j<ss;j++)
printf("%I64d %I64d %I64d\n",i,v[i][j].l,v[i][j].r);*/
LL A=0,l=v[i][0].l,r=v[i][0].l;
cnt[pre[l]]++;
for(j=0;j<ss;j++)
{
LL tl=v[i][j].l,tr=v[i][j].r;
//printf("%I64d %I64d %I64d %I64d\n",l,r,tl,tr);
while(tl<l)
{
l--;
A+=cnt[k^pre[l]];
cnt[pre[l]]++;
//l--;
}
while(tl>l)
{
//l++;
cnt[pre[l]]--;
A-=cnt[k^pre[l]];
l++;
}
while(r<tr)
{
r++;
A+=cnt[k^pre[r]];
cnt[pre[r]]++;
}
ans[v[i][j].id]=A;
}
for(j=l;j<=r;j++)
cnt[pre[j]]=0;
}
for(i=1;i<=m;i++)
printf("%I64d\n",ans[i]);
//puts("...");
return 0;
}