【洛谷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;
}