传送门
简单可持久化01trie树。
实际上这东西跟可持久化线段树貌似是一个东西啊。
要维护题目给出的信息,就需要维护前缀异或和并且把它们插入一棵01trie树,然后利用贪心的思想在上面递归就行了,因为01trie树的深度是
的,因此单次查询的效率就是
的,因此总时间复杂度是
的。
代码:
#include<bits/stdc++.h>
#define N 300005
using namespace std;
int sum[600005],rt[300005*100],n,m,tot=0,cnt=0;
struct Node{int l,r,cnt;}T[300005*100];
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
int ans=0;
inline void update(int&p,int las,int v,int dep){
T[p=++tot]=T[las],++T[p].cnt;
if(dep==-1)return;
int op=(v>>dep)&1;
if(!op)update(T[p].l,T[las].l,v,dep-1);
else update(T[p].r,T[las].r,v,dep-1);
}
inline void query(int ql,int qr,int v,int dep){
if(dep==-1)return;
int op=(v>>dep)&1;
op^=1;
if(!op){
if(T[T[qr].l].cnt-T[T[ql].l].cnt)ans+=(1<<dep),query(T[ql].l,T[qr].l,v,dep-1);
else query(T[ql].r,T[qr].r,v,dep-1);
}
else{
if(T[T[qr].r].cnt-T[T[ql].r].cnt)ans+=(1<<dep),query(T[ql].r,T[qr].r,v,dep-1);
else query(T[ql].l,T[qr].l,v,dep-1);
}
}
int main(){
n=read()+1,m=read(),rt[0]=0,T[0].l=T[0].r=T[0].cnt=0;
for(int i=2;i<=n;++i)sum[i]=sum[i-1]^read();
for(int i=1;i<=n;++i)update(rt[i],rt[i-1],sum[i],25);
while(m--){
char s[5];
scanf("%s",s);
if(s[0]=='A')++n,sum[n]=sum[n-1]^read(),update(rt[n],rt[n-1],sum[n],25);
else{
int l=read(),r=read(),x=read()^sum[n];
ans=0;
query(rt[l-1],rt[r],x,25);
cout<<ans<<'\n';
}
}
return 0;
}