题意:中文题。
分析:问题等价于求一个x与区间a[l]~a[r]之间的最大异或和。转为二进制树建可持久化字典树,在区间内跑最大值。O(nlogn)
代码:
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<bitset>
#include<math.h>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
const int N=300010;
const int MAX=100000000;
const int mod=100000000;
const int MOD1=1000000007;
const int MOD2=1000000009;
const double EPS=0.00000001;
typedef long long ll;
const ll MOD=998244353;
const ll INF=10000000010;
typedef double db;
typedef unsigned long long ull;
char s[4];
int siz,e[30],a[2*N],root[2*N],tr[50*N][2],sum[50*N];
int add(int x,int z) {
int i,y,t,ret=siz+1;
siz++;y=siz;sum[y]=sum[x]+1;
for (i=23;i>=0;i--) {
t=(z&e[i])>>i;
tr[y][0]=tr[x][0];tr[y][1]=tr[x][1];
tr[y][t]=++siz;y=tr[y][t];
x=tr[x][t];sum[y]=sum[x]+1;
}
return ret;
}
int query(int x,int y,int z) {
int i,t,ret=0;
for (i=23;i>=0;i--) {
t=(z&e[i])>>i;
if (sum[tr[y][t^1]]>sum[tr[x][t^1]]) {
ret+=e[i];x=tr[x][t^1];y=tr[y][t^1];
} else { x=tr[x][t];y=tr[y][t]; }
}
return ret;
}
int main()
{
int i,n,m,l,r,x;
e[0]=1;for (i=1;i<30;i++) e[i]=2*e[i-1];
scanf("%d%d", &n, &m);
n++;a[1]=0;
for (i=2;i<=n;i++) scanf("%d", &a[i]);
for (i=1;i<=n;i++) {
a[i]^=a[i-1];root[i]=add(root[i-1],a[i]);
}
while (m--) {
scanf("%s", s);
if (s[0]=='A') {
n++;scanf("%d", &a[n]);
a[n]^=a[n-1];root[n]=add(root[n-1],a[n]);
} else {
scanf("%d%d%d", &l, &r, &x);
printf("%d\n", query(root[l-1],root[r],x^a[n]));
}
}
return 0;
}