JZOJ 3184. 【GDOI2013模拟7】最大异或和

最大异或和

可持久化字典树经典题
题目网上自己找
来波模板

\(Code\)

#include<cstdio>
#include<iostream>
using namespace std;

const int N = 6e5 + 5;
int n , m , a[N] , size , s[N] , t[30 * N][2] , sum[60 * N] , rt[N];

inline void update(int u , int v , int x)
{
	for(register int i = 28; i >= 0; i--)
	{
		int c = (x >> i) & 1;
		sum[v] = sum[u] + 1;
		t[v][c] = ++size;
		t[v][c ^ 1] = t[u][c ^ 1];
		v = t[v][c] , u = t[u][c];
	}
	sum[v] = sum[u] + 1;
}

inline int query(int u , int v , int x)
{
	int res = 0;
	for(register int i = 28; i >= 0; i--)
	{
		int c = (x >> i) & 1 , k = sum[t[v][c ^ 1]] - sum[t[u][c ^ 1]];
		if (k) res += 1 << i , u = t[u][c ^ 1] , v = t[v][c ^ 1];
		else u = t[u][c] , v = t[v][c];
	}
	return res;
}

int main()
{
	scanf("%d%d" , &n , &m);
	for(register int i = 1; i <= n; i++) scanf("%d" , &a[i]) , s[i] = s[i - 1] ^ a[i];
	for(register int i = 1; i <= n; i++) update(rt[i - 1] , rt[i] = ++size , s[i]);
	int l , r , x;
	char op[3];
	while (m--)
	{
		scanf("%s" , op);
		if (op[0] == 'A') 
		{
			n++;
			scanf("%d" , a + n);
			s[n] = s[n - 1] ^ a[n];
			update(rt[n - 1] , rt[n] = ++size , s[n]);
		}
		else {
			scanf("%d%d%d" , &l , &r , &x);
			--l , --r;
			if (l == r && l == 0) printf("%d\n" , s[n] ^ x);
			else printf("%d\n" , query(rt[max(l - 1 , 0)] , rt[r] , s[n] ^ x));
		}
	}
}
posted @ 2020-08-06 15:39  leiyuanze  阅读(101)  评论(0编辑  收藏  举报