对原序列取前缀异或值,变成pre[1...N],然后询问等价于求max{a[N]^x^pre[i]}(l-1<=i<=r-1)。
#include<cstdio> #define INF 2147483647 #define N 300001 #define MAXBIT 25 int root[N<<1],ch[(N<<1)*(MAXBIT+1)][2],sz[(N<<1)*(MAXBIT+1)],tot; int query(int L,int R,int W)//询问a[L...R]中W与其的最大异或值 { int ans=0; L=root[L];R=root[R+1]; for(int i=MAXBIT-1;i>=0;--i) { int Bit=(W>>i&1^1); if(sz[ch[R][Bit]]-sz[ch[L][Bit]]==0) Bit^=1; else ans+=1<<i; R=ch[R][Bit]; L=ch[L][Bit]; } return ans; } void add(int now,int W)//先add(1,0),再add(2...n+1,a[1...n]) { int old=root[now-1]; root[now]=++tot; now=root[now]; for(int i=MAXBIT-1;i>=0;--i) { int Bit=(W>>i&1); sz[now]=sz[old]+1; ch[now][Bit^1]=ch[old][Bit^1]; ch[now][Bit]=++tot; now=ch[now][Bit]; old=ch[old][Bit]; } sz[now]=sz[old]+1; } char op[2]; int a[N<<1],x,y,v,n,m,en; int main() { add(1,0); scanf("%d%d",&n,&m); en=n; for(int i=1;i<=n;++i) { scanf("%d",&a[i]); a[i]^=a[i-1]; add(i+1,a[i]); } for(;m;--m) { scanf("%s",op); if(op[0]=='A') { scanf("%d",&a[++en]); a[en]^=a[en-1]; add(en+1,a[en]); } else { scanf("%d%d%d",&x,&y,&v); printf("%d ",query(x-1,y-1,v^a[en])); } } return 0; }