BZOJ5301P4462 [CQOI2018]异或序列

莫队裸题。只不过这道题维护了前缀XOR,所以我们更新的时候需要一些小操作,然后就没了

代码

//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=1e5+50;
struct Mo
{
	int l,r,id,ans;
}e[M];
int n,m,k,block,ans=0;
int bloc[M],c[M],xo[M];
inline bool cmp1(Mo a,Mo b)
{
	if (bloc[a.l]==bloc[b.l]) return a.r<b.r;
	return a.l<b.l;
}
inline bool cmp2(Mo a,Mo b){return a.id<b.id;}
inline int read()
{
	int x=0;char ch=getchar();
	while (ch>'9'||ch<'0') ch=getchar();
	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x;
}
inline void add(int x)
{
	return (void)(ans+=xo[c[x]^k],xo[c[x]]++);
}
inline void del(int x)
{
	return (void)(xo[c[x]]--,ans-=xo[c[x]^k]);
}
inline void slove()
{
	int l=1,r=0;xo[0]=1;
	for (int i=1;i<=m;i++)
	{
		while (l<e[i].l) del((l++)-1);
		while (l>e[i].l) add((--l)-1);
		while (r<e[i].r) add(++r);
		while (r>e[i].r) del(r--);
		e[i].ans=ans;
	}
	return ;
}
int main()
{
	n=read(),m=read();k=read();block=sqrt(n);
	for (int i=1;i<=n;i++) c[i]=read(),c[i]^=c[i-1];
	for (int i=1;i<=n;i++) bloc[i]=(i-1)/block+1;
	for (int i=1;i<=m;i++) e[i].l=read(),e[i].r=read(),e[i].id=i;
	sort(e+1,e+m+1,cmp1);
	slove();
	sort(e+1,e+m+1,cmp2);
	for (int i=1;i<=m;i++)
		printf("%d\n",e[i].ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/acerandaker/article/details/81064424