【可持久化0/1Trie】【P4735】最大异或和

Limitation

$1 \leq n,~m \leq 3 \times 10^5$

$0 \leq A_i \leq 10^7$

Code

#include <cstdio>
#include <algorithm>

const int maxn = 600005;
const int upceil = 25;
const int tupceil = 24;
const int maxt = maxn * upceil;

struct Tree {
Tree *ch[2];
int v[2];

Tree() { ch[0] = ch[1] = NULL; v[0] = v[1] = 0; }
};
Tree *rot[maxn], *pool[maxt], qwq[maxt];

int n, m, sum, top;
int MU[maxn];

void build(Tree *u, Tree *pre, const int v, int p);
int query(const Tree *const pre, const Tree *const u, const int v, const int p);

int main() {
freopen("1.in", "r", stdin);
qr(n); qr(m);
for (int i = 0; i < maxt; ++i) pool[i] = qwq + i;
build(rot[0] = pool[top++], NULL, 0, tupceil);
for (int i = 1, x; i <= n; ++i) {
x = 0; qr(x);
build(rot[i] = pool[top++], rot[i - 1], sum ^= x, tupceil);
}
for (int a, b, c; m; --m) {
a = 0;
do a = IPT::GetChar(); while ((a != 'A') && (a != 'Q'));
if (a == 'A') {
a = 0; qr(a);
build(rot[n + 1] = pool[top++], rot[n], sum ^= a, tupceil);
++n;
} else {
a = b = c = 0; qr(a); qr(b); qr(c);
if (b == 1) {
qw(sum ^ c, '\n', true);
continue;
}
qw(query(rot[std::max(0, a - 2)], rot[b - 1], sum ^ c, tupceil) ^ sum ^ c, '\n', true);
}
}
return 0;
}

void build(Tree *u, Tree *pre, const int v, int p) {
while (~p) {
if (pre) *u = *pre;
int x = (v & (1 << p)) >> p;
++u->v[x];
u = u->ch[x] = pool[top++];
if (pre) pre = pre->ch[x];
--p;
}
}

int query(const Tree *pre, const Tree *u, const int v, int p) {
int _ret = 0;
while (~p) {
int x = ((v & (1 << p)) >> p) ^ 1, y = u->v[x] - (pre ? pre->v[x] : 0);
if (!y) x ^= 1;
_ret |= (x << p);
u = u->ch[x];
if (pre) pre = pre->ch[x];
--p;
}
return _ret;
}

posted @ 2019-07-16 18:49  一扶苏一  阅读(243)  评论(0编辑  收藏  举报