裸的可持久化字典树。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=600005;
int root[maxn];
int cnt;
int fa[30];
namespace Trie{
int sum[maxn*25];
int ch[maxn*25][2];
void init(){
memset(ch,0,sizeof(ch));
memset(sum,0,sizeof(sum));
}
void insert(int pre,int no,int val){
for(int i=23;i>=0;i--){
ch[no][0]=ch[pre][0];
ch[no][1]=ch[pre][1];
sum[no]=sum[pre]+1;
int w=(val>>i)&1;
ch[no][w]=++cnt;
no=ch[no][w];
pre=ch[pre][w];
}
sum[no]=sum[pre]+1;
}
int query(int pre,int no,int val){
int s=0;
for(int i=23;i>=0;i--){
int w=(val>>i)&1;
if(sum[ch[no][w^1]]-sum[ch[pre][w^1]]>0){
s+=fa[i];
w=w^1;
}
no=ch[no][w];
pre=ch[pre][w];
}
return s;
}
}
char c[2];
int main()
{
for(int i=0;i<30;i++) fa[i]=1<<i;
int n,m;
cin>>n>>m;
int all=0;
for(int i=1;i<=n;i++){
root[i]=++cnt;
Trie::insert(root[i-1],root[i],all);
int p;
scanf("%d",&p);
all^=p;
}
while(m--){
scanf("%s",c);
if(c[0]=='A'){
int x;
scanf("%d",&x);
root[n+1]=++cnt;
n++;
Trie::insert(root[n-1],root[n],all);
all^=x;
}
else{
int l,r,x;
scanf("%d%d%d",&l,&r,&x);
printf("%d\n",Trie::query(root[l-1],root[r],x^all));
}
}
}