洛谷P4735 最大异或和 题解 可持久化字典树模板题
题目链接:https://www.luogu.com.cn/problem/P4735
解题思路:
可持久化字典树 模板题。
参考思路:https://www.luogu.com.cn/article/swqlf5n3
示例程序:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 6e5 + 5;
struct Node {
int son[2], cnt;
} tr[maxn*20];
int rt[maxn] = { 1 }, idx = 1;
int cpy_node(int u) {
tr[++idx] = tr[u];
return idx;
}
int n, m, a[maxn], sum[maxn];
void ins(int pu, int u, int val) {
for (int d = 24; d >= 0; d--) {
int x = (val >> d) & 1;
tr[u].son[x^1] = tr[pu].son[x^1];
tr[u].son[x] = cpy_node(tr[pu].son[x]);
pu = tr[pu].son[x];
u = tr[u].son[x];
tr[u].cnt++;
}
}
int query(int u1, int u2, int val) {
int ans = 0;
for (int d = 24; d >= 0; d--) {
int x = (val >> d) & 1;
int s1 = tr[u1].son[x^1],
s2 = tr[u2].son[x^1];
int cnt = tr[s2].cnt - tr[s1].cnt;
if (cnt > 0) {
ans += (1 << d);
u1 = s1;
u2 = s2;
}
else {
u1 = tr[u1].son[x];
u2 = tr[u2].son[x];
}
}
return ans;
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%d", a+i);
sum[i] = sum[i-1] ^ a[i];
}
for (int i = 0; i <= n; i++) {
if (!i) ins(rt[0], rt[0], 0);
else {
rt[i] = ++idx;
ins(rt[i-1], rt[i], sum[i]);
}
}
char op[2];
while (m--) {
scanf("%s", op);
if (op[0] == 'A') {
n++;
scanf("%d", a+n);
sum[n] = sum[n-1] ^ a[n];
rt[n] = ++idx;
ins(rt[n-1], rt[n], sum[n]);
}
else {
int l, r, x;
scanf("%d%d%d", &l, &r, &x);
int ans = 0;
if (l == 1) {
ans = sum[n] ^ x;
l++;
}
if (l <= r)
ans = max(ans, query(rt[l-2], rt[r-1], sum[n] ^ x));
printf("%d\n", ans);
}
}
return 0;
}
浙公网安备 33010602011771号