可持久化Trie 01Trie
可持久化Trie
基本上所有的可持久化数据结构都可以理解为继承与修改,继承之前的,再加入新的修改。
蛮好写的,size数组可以理解为在同一位深度的节点是第几个添加的,这样就为判断是在l前还是在l后准备了依据。
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<sstream>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<deque>
#include<cstdlib>
#include<ctime>
#define dd double
#define ld long double
#define ll long long
#define ull unsigned long long
#define N 50000000
#define M number
using namespace std;
const int INF=0x3f3f3f3f;
inline int read(){
int x=0,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();}
return x*f;
}
struct PRE_TRIE{
int root[N],ch[N][2],size[N],tail,tot;
inline void insert(int sum){
root[++tot]=++tail;
int p=root[tot-1],q=root[tot];
for(int i=30;i>=0;i--){
int w=(sum>>i)&1;
size[q]=size[p]+1;
ch[q][w]=++tail;
ch[q][w^1]=ch[p][w^1];
q=ch[q][w];p=ch[p][w];
}
size[q]=size[p]+1;
}
inline int ask_max(int sum,int l,int r){
int p=root[l-1],q=root[r],ans=0;
for(int i=30;i>=0;i--){
int w=(sum>>i)&1;
if(size[ch[q][w^1]]-size[ch[p][w^1]]>0) q=ch[q][w^1],p=ch[p][w^1],ans+=(1<<i);
else q=ch[q][w],p=ch[p][w];
}
return ans;
}
};
PRE_TRIE trie;
int n,m,xhe;
int main(){
n=read();m=read();
trie.insert(0);
for(int i=1;i<=n;i++){
int x=read();xhe^=x;
trie.insert(xhe);
}
for(int i=1;i<=m;i++){
char c=getchar();
while(c!='A'&&c!='Q') c=getchar();
if(c=='A'){
int x=read();xhe^=x;
trie.insert(xhe);
}
else{
int l=read(),r=read(),x=read();
printf("%d\n",trie.ask_max(x^xhe,l,r));
}
}
return 0;
}