我的脑回路可能比较奇怪。
我们对这些询问离线,将所得序列${a}$的后缀和建$n$棵可持久化$trie$。
对于一组询问$(l,r,x)$,我们在主席树上询问第$l$棵树$-$第r$+1$棵树中与$suma[n'] xor x$异或的最大值即可。
这个时间复杂度是$O(n log a)$的。
1 #include<bits/stdc++.h> 2 #define M 600005 3 using namespace std; 4 5 struct trie{int a[2],sum=0;}a[M*30]; 6 int root[M]={0},use=0; 7 void updata(int &x,int dep,int Val){ 8 bool k=Val&(1<<dep); 9 a[++use]=a[x]; a[x=use].sum++; 10 if(dep==-1) return; 11 updata(a[x].a[k],dep-1,Val); 12 } 13 int query(int x,int y,int Val){ 14 int res=0; 15 for(int i=29;~i;i--){ 16 bool k=Val&(1<<i); k^=1; 17 int cnt=a[a[x].a[k]].sum-a[a[y].a[k]].sum; 18 if(cnt) res|=1<<i,x=a[x].a[k],y=a[y].a[k]; 19 else x=a[x].a[k^1],y=a[y].a[k^1]; 20 } 21 return res; 22 } 23 24 int val[M]={0}; 25 int n,m; 26 int nown[M]={0},l[M]={0},r[M]={0},X[M]={0},cnt=0; 27 int main(){ 28 scanf("%d%d",&n,&m); 29 for(int i=1;i<=n;i++) scanf("%d",val+i); 30 while(m--){ 31 char op[10]; scanf("%s",op); 32 if(op[0]=='A') {scanf("%d",val+(++n)); continue;} 33 nown[++cnt]=n; 34 scanf("%d%d%d",l+cnt,r+cnt,X+cnt); 35 } 36 for(int i=n;i;i--){ 37 val[i]^=val[i+1]; root[i]=root[i+1]; 38 updata(root[i],29,val[i]); 39 } 40 for(int i=1;i<=cnt;i++){ 41 printf("%d ",query(root[l[i]],root[r[i]+1],val[nown[i]+1]^X[i])); 42 } 43 }