【BZOJ3261】— 最大异或和(可持久化0/1Trie)
终于开始学可持久化数据结构了
考虑到类似于主席树,每次加一个数只会增加个节点
所以就直接对于每一次的每个节点记录一个表示前个数中有多少个数经过了这个点
询问的时候看一下就知道~之间存不存在数经过该点了
注意要先建一个号点处理询问~的情况
#include<bits/stdc++.h>
using namespace std;
#define gc getchar
inline int read(){
char ch=gc();int res=0,f=1;
while(!isdigit(ch)){if(ch=='-')f=-f;ch=gc();}
while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=gc();
return res*f;
}
#undef gc
const int N=600005;
const int Log=25;
int n,m,a[N],b[N],rt[N],sum[N*Log],son[N*Log][2],cnt;
inline int insert(int u,int val){
int tmp=++cnt,now=cnt;
for(int i=Log-1;~i;i--){
son[now][1]=son[u][1],son[now][0]=son[u][0];
sum[now]=sum[u]+1;int t=(val&(1<<i))?1:0;
u=son[u][t],son[now][t]=++cnt,now=cnt;
}
sum[now]=sum[u]+1;return tmp;
}
inline int query(int l,int r,int val){
int tmp=0;
for(int i=Log-1;~i;i--){
int t=(val&(1<<i))?1:0;
if(sum[son[r][t^1]]-sum[son[l][t^1]])
tmp+=(1<<i),r=son[r][t^1],l=son[l][t^1];
else r=son[r][t],l=son[l][t];
}
return tmp;
}
int main(){
n=read(),m=read();
for(int i=1;i<=n;i++)a[i]=read();
for(int i=0;i<=n;i++)b[i]=b[i-1]^a[i];
rt[0]=insert(0,0);
for(int i=0;i<=n;i++)rt[i]=insert(rt[i-1],b[i]);
char c[5];
for(int i=1;i<=m;i++){
scanf("%s",c);
if(c[0]=='A'){
n++,a[n]=read(),b[n]=b[n-1]^a[n];
rt[n]=insert(rt[n-1],b[n]);
}
else{
int l=read()-1,r=read()-1,k=read();
cout<<query(rt[l-1],rt[r],b[n]^k)<<'\n';
}
}
}