luogu4462 异或序列

题目大意

给出n,m,k,有n个数的序列,m次询问一段区间,问异或和等于K的子区间的个数。

题解

本题一看就是莫队。但要解决该题需要以下性质:

定理:

$$a\oplus b=c\Leftrightarrow a\oplus c=b\Leftrightarrow b\oplus c=a$$

推论:

$$\oplus_{i=l}^r A_i= \oplus_{i=1}^r A_i \oplus \oplus_{i-1}^{l-1}A_i$$

因此,我们对每个节点维护它的前缀和。比如说,如果右方加入一个节点,因为右方r的前缀和异或左面l的前缀和的结果表示的就是[l+1,r]的异或和。此时增加的满足条件的子区间的个数,根据定理,便是当前区间中前缀和的值异或上新加入的节点的前缀和的值等于K的点的数量。这就可以用莫队的桶来维护了。

#define _DEBUG

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;


const int MAX_N = 100010;
int K;
int BASE;

struct CaptainMo
{
	int N, OpCnt, Sum;
	
	int PrefixValCnt[MAX_N];
	
	struct Data
	{
		int CurVal, Prefix;
	}_datas[MAX_N];
	
	struct Query
	{
		int L, R;
		int Ans;
		Query *This;
		
		Query():This(this){}
		
		bool operator < (const Query& a)const
		{
			return L / BASE == a.L / BASE ? R < a.R : L / BASE < a.L / BASE;
		}
	}_qs[MAX_N], temp[MAX_N];
	
	void InRange(Data cur)
	{
		Sum += PrefixValCnt[cur.Prefix ^ K];
		PrefixValCnt[cur.Prefix]++;
	}
	
	void OutRange(Data cur)
	{
		Sum -= PrefixValCnt[cur.Prefix ^ K];
		PrefixValCnt[cur.Prefix]--;
	}
	
	void Init()
	{
		for(int i = 1; i <= OpCnt; i++)
			_qs[i].L--;
		for(int i = 1; i <= N; i++)
			_datas[i].Prefix = _datas[i - 1].Prefix ^ _datas[i].CurVal;
		BASE = sqrt(N);
		memcpy(temp, _qs, sizeof(_qs));
		sort(temp + 1, temp + OpCnt + 1);
	}
	
	void Proceed()
	{
		int l = 0, r = 0;
		Sum = 0;
		PrefixValCnt[0] = 1;
		for(int i = 1; i <= OpCnt; i++)
		{
			while(r > temp[i].R)
				OutRange(_datas[r--]);
			while(r < temp[i].R)
				InRange(_datas[++r]);
			while(l < temp[i].L)
				OutRange(_datas[l++]);
			while(l > temp[i].L)
				InRange(_datas[--l]);
			temp[i].This->Ans = Sum;
		}
	}
}g;

int main()
{
	scanf("%d%d%d", &g.N, &g.OpCnt, &K);
	for(int i = 1; i <= g.N; i++)
		scanf("%d", &g._datas[i].CurVal);
	for(int i = 1; i <= g.OpCnt; i++)
		scanf("%d%d", &g._qs[i].L, &g._qs[i].R);
	g.Init();
	g.Proceed();
	for(int i = 1; i <= g.OpCnt; i++)
		printf("%d\n", g._qs[i].Ans);
	return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/headboy2002/p/9219452.html