最大异或和题解
其实很简单了,
xor->分位操作
动态维护->只可能是可持久化0、1 trie 树了吧
然后每次加入新点便更新版本,
将查询\(\sum_{i=p}^{N} a[i] xor X(p \in [l,r])\),(这里的\(\sum!=+, = xor\)),
变为\((\sum_{i=1}^{N} xor X) xor \sum_{i=1}^{p-1} (p-1 \in [l-1,r-1])\)
将每个点变为前缀和选出与\(sum[N] xor x\)异或起来最大的值,在tire 树上一步一步走即可,
#include
using namespace std;
const int N=3e5+7,M=6e5+7,P=27;
int n,m,t,num,cnt=1,a[M],son[M*P][2],pre[M*P],tmp[P],p,q,t1,t2,t3,rt[M];
char c[12];
inline int read(){
int T=0,F=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') F=-1; ch=getchar();}
while(ch>='0'&&ch<='9') T=(T<<3)+(T<<1)+(ch-48),ch=getchar();
return F*T;
}
void update(int x,int y,int z){
for(int i=24;i>=0;--i) tmp[25-i]=((x>>i)&1);
rt[z]=++cnt,p=cnt;
for(int i=1;i<=25;++i){
son[p][tmp[i]^1]=son[y][tmp[i]^1];
son[p][tmp[i]]=++cnt,pre[cnt]=z;
p=cnt,y=son[y][tmp[i]];
}
}
int query(int l,int r,int x){
p=rt[r],t=(a[num]^x); int ans=0;
for(int i=24;i>=0;--i) tmp[25-i]=(!((t>>i)&1));
for(int i=1;i<=25;++i){
t=son[p][tmp[i]];
if(t&&pre[t]>=l) p=son[p][tmp[i]],ans+=(1<<(25-i));
else{
if(son[p][tmp[i]^1]) p=son[p][tmp[i]^1];
else return ans;
}
}
return ans;
}
int main(){
n=read(),m=read(),num=n,rt[0]=1,p=1;
for(int i=1;i<=25;++i) son[p][0]=++cnt,p=cnt;
for(int i=1;i<=n;++i) a[i]=read(),a[i]^=a[i-1],update(a[i],rt[i-1],i);
for(int i=1;i<=m;++i){
scanf("%s",c),t1=read();
if(c[0]=='A') a[++num]=t1,a[num]^=a[num-1],update(a[num],rt[num-1],num);
else t2=read(),t3=read(),printf("%d\n",query(t1-1,t2-1,t3));
}
return 0;
}