- tire树相关
- 由于可能出现查询越界的情况,所以开始时要把初始数组整体向右移动一位
Code
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
const int N=6e5+100;
int tr[N*28][2],b[N],a[N],son[N*28],root[N],ans,tot,n,m,x,l,r;
char s,shit[30],fuck[30];
inline int read(){
int x=0;char ch=getchar();
while(isdigit(ch)==0)ch=getchar();
while(isdigit(ch)!=0){x=x*10+ch-'0';ch=getchar();}
return x;
}
void zip(int a,char s[]){
int top=28;
while(a){
if(a&1)s[top]='1';
else s[top]='0';
a>>=1;
top--;
}
per(i,top,1)s[i]='0';
}
void insert(int &now,int last,int len){
if(!now)now=++tot;
if(len==29){
son[now]=son[last]+1;
return;
}
int to=shit[len]-'0';
rep(i,0,1){
if(i!=to){
tr[now][i]=tr[last][i];
son[now]+=son[tr[last][i]];
}
}
insert(tr[now][to],tr[last][to],len+1);
son[now]+=son[tr[now][to]];
}
void search(int r,int l,int len){
if(len==29) return;
if(fuck[len]=='0'){
if(son[tr[r][1]]-son[tr[l][1]]){
ans|=1<<(28-len);
search(tr[r][1],tr[l][1],len+1);
}else{
search(tr[r][0],tr[l][0],len+1);
}
}else{
if(son[tr[r][0]]-son[tr[l][0]]){
ans|=1<<(28-len);
search(tr[r][0],tr[l][0],len+1);
}else{
search(tr[r][1],tr[l][1],len+1);
}
}
}
int main()
{
n=read(),m=read();
++n;rep(i,2,n)a[i]=read();
rep(i,1,n)b[i]=b[i-1]^a[i];
rep(i,1,n)zip(b[i],shit),insert(root[i],root[i-1],1);
while(m--){
scanf(" %c",&s);
if(s=='A'){
b[++n]=read();
b[n]^=b[n-1];
zip(b[n],shit);insert(root[n],root[n-1],1);
}else{
l=read(),r=read(),x=read();
x^=b[n],ans=0,zip(x,fuck);
search(root[r],root[l-1],1);
printf("%d\n",ans);
}
}return 0;
}