可持久化\(01Trie\)。感觉不是很会写,改天复习完主席树会再来学一次。
#include <bits/stdc++.h>
using namespace std;
const int N = 600010;
int s[N], rt[N], cnt[N * 25];
int max_size = 1, ch[N * 25][2];
void ins (int now, int pre, int x) {
for (int t = 25; t >= 0; --t) {
int i = (x >> t) & 1;
ch[now][!i] = ch[pre][!i]; //不修改的 -> 直接连起来
ch[now][i] = ++max_size; //修改的 -> 新建节点
cnt[ch[now][i]] = cnt[ch[pre][i]] + 1; //维护一个数的个数
now = ch[now][i], pre = ch[pre][i];
}
//只有在存在新节点的部分,cnt[now] 才会大于 cnt[pre]
}
int qry (int l, int r, int x) {
int ans = 0;
for (int t = 25; t >= 0; --t) {
int i = (x >> t) & 1;
if (cnt[ch[r][!i]] > cnt[ch[l][!i]]) {
ans += (1 << t);
l = ch[l][!i];
r = ch[r][!i];
} else {
l = ch[l][i];
r = ch[r][i];
}
//限制其不能向版本更低的地方走
//至少添加一个数, 不在i上就在!i上,不允许向cnt更低的地方走
}
return ans;
}
int n, m, x, l, r; char opt;
int main () {
cin >> n >> m;
rt[0] = ++max_size;
ins (rt[0], 0, 0);
for (int i = 1; i <= n; ++i) {
scanf ("%d", &s[i]);
s[i] ^= s[i - 1];
rt[i] = ++max_size;
ins (rt[i], rt[i - 1], s[i]);
}
for (int i = 1; i <= m; ++i) {
scanf (" %c", &opt);
if (opt == 'A') {
scanf ("%d", &x);
n = n + 1;
s[n] = s[n - 1] ^ x;
rt[n] = ++max_size;
ins (rt[n], rt[n - 1], s[n]);
} else {
scanf ("%d %d %d", &l, &r, &x); --l, --r;
if(l <= 0) {
printf ("%d\n", qry (0, rt[r], x ^ s[n]));
} else {
printf ("%d\n", qry (rt[l - 1], rt[r], x ^ s[n]));
}
}
}
return 0;
}