Trie维护序列前缀异或和,然后贪心找就可以啦。
#include <cstdio>
const int maxn = 600005, maxd = 26, maxnode = maxn * maxd;
int n, m, bin[maxd], num[maxn], son[maxnode][2], sum[maxnode], root[maxn], triecnt;
inline int iread() {
int f = 1, x = 0; char ch = getchar();
for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
return f * x;
}
inline void insert(int &pos, int c) {
int now = ++triecnt, last = pos; pos = now;
for(int i = maxd - 1; i >= 0; i--) {
son[now][0] = son[last][0]; son[now][1] = son[last][1];
sum[now] = sum[last] + 1;
bool ind = c & bin[i];
last = son[last][ind];
now = son[now][ind] = ++triecnt;
}
sum[now] = sum[last] + 1;
}
inline int query(int l, int r, int c) {
int ans = 0;
for(int i = maxd - 1; i >= 0; i--) {
bool ind = c & bin[i];
if(sum[son[r][ind ^ 1]] - sum[son[l][ind ^ 1]])
ans += bin[i], l = son[l][ind ^ 1], r = son[r][ind ^ 1];
else l = son[l][ind], r = son[r][ind];
}
return ans;
}
int main() {
freopen("xor.in", "r", stdin); freopen("xor.out", "w", stdout);
bin[0] = 1; for(int i = 1; i < maxd; i++) bin[i] = bin[i - 1] << 1;
n = iread(); m = iread(); num[1] = 0; ++n;
for(int i = 2; i <= n; i++) num[i] = iread() ^ num[i - 1];
for(int i = 1; i <= n; i++) insert(root[i] = root[i - 1], num[i]);
while(m--) {
char ch = getchar(); for(; ch != 'A' && ch != 'Q'; ch = getchar());
if(ch == 'A') {
++n; num[n] = iread() ^ num[n - 1];
insert(root[n] = root[n - 1], num[n]);
} else {
int l = iread(), r = iread(), c = iread();
printf("%d\n", query(root[l - 1], root[r], c ^ num[n]));
}
}
return 0;
}