【洛谷P4735】最大异或和

题面

题解

这个题目要求区间最大异或和,在可持久化$\text{trie}$上贪心即可。

(常数太大过不了洛谷的毒瘤数据)

代码

#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#define RG register
#define file(x) freopen(#x".in", "r", stdin);freopen(#x".out", "w", stdout);
#define clear(x, y) memset(x, y, sizeof(x))

inline int read()
{
	int data = 0, w = 1; char ch = getchar();
	while(ch != '-' && (!isdigit(ch))) ch = getchar();
	if(ch == '-') w = -1, ch = getchar();
	while(isdigit(ch)) data = data * 10 + (ch ^ 48), ch = getchar();
	return data * w;
}

const int maxn(600010);
class Trie
{
		friend int query(int, int, int);
	private:
		struct node
		{
			node *son[2]; int size;
			node() : size(0) { }
		}*root;
		static inline int size(node *x) { return x ? x -> size : 0; }
		inline node *newnode()
		{
			static node *null = new node;
			null -> son[0] = null -> son[1] = null;
			node *x = new node; x -> son[0] = x -> son[1] = null;
			return x;
		}
	public:
		Trie() { }
		Trie(int) { root = newnode(); }
		void insert(int);
};

void Trie::insert(int val)
{
	node *x = newnode(), *y = root;
	x -> size = size(y) + 1, root = x;
	for(int i = 25, s; ~i; --i)
	{
		s = val >> i & 1;
		if(y)
		{
			x -> son[!s] = y -> son[!s];
			(x = x -> son[s] = newnode()) -> size = size(y -> son[s]) + 1;
			y = y -> son[s];
		}
		else ++(x = x -> son[s] = newnode()) -> size;
	}
}

int n, m, sum; char s[3];
Trie tree[maxn], tmp(0);

int query(int l, int r, int val)
{
	Trie::node *x, *y = tree[r].root; int ans = 0;
	if(l == 0) x = tmp.root;
	else x = tree[l - 1].root;
	for(int i = 25, s; ~i; --i)
	{
		s = val >> i & 1;
		if(Trie::size(y -> son[!s]) - Trie::size(x -> son[!s]) > 0)
			ans |= (1 << i), x = x -> son[!s], y = y -> son[!s];
		else x = x -> son[s], y = y -> son[s];
	}
	return ans;
}

int main()
{
#ifndef ONLINE_JUDGE
	file(cpp);
#endif
	n = read(), m = read();
	tree[0].insert(0);
	for(RG int i = 1, t; i <= n; i++)
		t = read(), tree[i] = tree[i - 1], tree[i].insert(sum ^= t);
	while(m--)
	{
		scanf("%s", s); int l, r, x;
		if(s[0] == 'A') ++n, tree[n] = tree[n - 1], tree[n].insert(sum ^= read());
		else l = read(), r = read(), x = read(), printf("%d\n", query(l - 1, r - 1, sum ^ x));
	}
	return 0;
}
posted @ 2018-12-25 21:02  xgzc  阅读(160)  评论(0编辑  收藏  举报