这个似乎也不是好难啊
但是可持久化Trie还是可以干许多线性基不能干的事。
什么是可持久化Trie?
顾名思义:是一种可以持久化的Trie树
他的建树方式和键值式线段树方式类似
也支持版本的减法
查询的本质是贪心:
利用版本减法判断第K位上的Trie值是不是成立
以此向下查询
#include<bits/stdc++.h>
using namespace std;
inline void read(int &x){
x=0;
int f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
x*=f;
}
const int N=6e5+100;
int bin[30]={};
int root[N]={};
struct Trie{
int sum[N*24];
int ch[N*24][2];
int cnt;
inline int insert(int x,int val){
int tmp=++cnt;
int y=cnt;
for(int i=23;i>=0;i--){
ch[y][0]=ch[x][0];
ch[y][1]=ch[x][1];
sum[y]=sum[x]+1;
int t=val&(bin[i]);
t>>=i;
x=ch[x][t];
ch[y][t]=++cnt;
y=ch[y][t];
}
sum[y]=sum[x]+1;
return tmp;
}
inline int query(int l,int r,int val){
int tmp=0;
for(int i=23;i>=0;i--){
int t=val&(bin[i]);
t>>=i;
if(sum[ch[r][t^1]]-sum[ch[l][t^1]]){
tmp+=bin[i];
r=ch[r][t^1];
l=ch[l][t^1];
}
else l=ch[l][t],r=ch[r][t];
}
return tmp;
}
}T;
int n,m;
int A[N]={};
int B[N]={};
int main(){
// freopen("bzoj3261.in","r",stdin);
// freopen("bzoj3261.out","w",stdout);
read(n);
read(m);
bin[0]=1;
for(int i=1;i<=23;i++)bin[i]=bin[i-1]*2;
n++;
for(int i=2;i<=n;i++)read(A[i]);
for(int i=1;i<=n;i++)B[i]=B[i-1]^A[i];
for(int i=1;i<=n;i++){
// cout<<B[i]<<'\n';
root[i]=T.insert(root[i-1],B[i]);
}
// cout<<query(root[1],root[n],0)<<'\n';
for(int i=1;i<=m;i++){
char opt[2];
scanf("%s",opt);
if(opt[0]=='A'){
int x;
n++;
read(x);
B[n]=B[n-1]^x;
root[n]=T.insert(root[n-1],B[n]);
}
else{
int l,r,x;
read(l);
read(r);
read(x);
cout<<T.query(root[l-1],root[r],B[n]^x)<<'\n';
}
// cout<<i<<" "<<'\n';
}
return 0;
}