#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxl 2000010
using namespace std;
long long n,m,k,size,cnt,res;
long long a[maxl],sum[maxl],pos[maxl],l[maxl],r[maxl];
long long num[maxl];
long long ans[maxl];
struct que
{
long long l,r,ind;
}q[maxl];
bool cmp(const que &x,const que &y)
{
if(pos[x.l]==pos[y.l])
return x.r<y.r;
else
return pos[x.l]<pos[y.l];
}
void prework()
{
memset(num,0,sizeof(num));
size=sqrt(n);cnt=n/size;
if(n%size) cnt++;
for(long long i=1;i<=n;i++)
scanf("%I64d",&a[i]),sum[i]=sum[i-1]^a[i];
for(long long i=1;i<=cnt;i++)
{
l[i]=(i-1)*size+1;r[i]=min(i*size,n);
for(long long j=l[i];j<=r[i];j++)
pos[j]=i;
}
for(long long i=1;i<=m;i++)
{
scanf("%I64d%I64d",&q[i].l,&q[i].r);
q[i].ind=i;
}
sort(q+1,q+1+m,cmp);
}
void mainwork()
{
long long left=1,right=0;
res=0;
num[0]=1;
for(long long i=1;i<=m;i++)
{
while(left<q[i].l)
{
num[sum[left-1]]--; //k=0是要先减这个
res-=num[sum[left-1]^k];
left++;
}
while(left>q[i].l)
{
left--;
res+=num[sum[left-1]^k];
num[sum[left-1]]++; //k=0时要后加这个
}
while(right<q[i].r)
{
right++;
res+=num[sum[right]^k];
num[sum[right]]++;
}
while(right>q[i].r)
{
num[sum[right]]--;
res-=num[sum[right]^k];
right--;
}
ans[q[i].ind]=res;
}
}
void print()
{
for(long long i=1;i<=m;i++)
printf("%I64d\n",ans[i]);
}
int main()
{
while(~scanf("%I64d%I64d%I64d",&n,&m,&k))
{
prework();
mainwork();
print();
}
return 0;
}CodeForces 617E
最新推荐文章于 2021-02-17 23:52:14 发布
本文介绍了一种使用预处理和滑动窗口技术进行区间查询优化的方法,通过将数据划分为固定大小的区块并预先计算区块内特定值的出现次数,实现了快速响应大量区间查询的需求。
516

被折叠的 条评论
为什么被折叠?



