洛谷 P4735 最大异或和
一、题目:
二、思路:
这是一道可持久化trie的板子题。
三、代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define mem(s,v) memset(s,v,sizeof(s))
using namespace std;
inline LL read(void){
LL 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 f*x;
}
const int maxn=600010;
int n,m;
int a[maxn],sum[maxn],root[maxn];
int trie[maxn*24][2],sz;
int latest[maxn*24];
void insert(int i,int k,int p,int q){
if(k<0){
latest[q]=i;
return;
}
int c=sum[i]>>k&1;
if(p)trie[q][c^1]=trie[p][c^1];
trie[q][c]=++sz;
insert(i,k-1,trie[p][c],trie[q][c]);
latest[q]=max(latest[trie[q][0]],latest[trie[q][1]]);
}
int ask(int now,int val,int k,int limit){
if(k<0){return sum[latest[now]]^val;}
int c=val>>k&1;
if(latest[trie[now][c^1]]>=limit)
return ask(trie[now][c^1],val,k-1,limit);
else
return ask(trie[now][c],val,k-1,limit);
}
int main(){
n=read();m=read();
latest[0]=-1;
root[0]=++sz;
insert(0,23,0,root[0]);
for(register int i=1;i<=n;++i){
a[i]=read();
sum[i]=sum[i-1]^a[i];
root[i]=++sz;
insert(i,23,root[i-1],root[i]);
}
while(m--){
char op[3];scanf("%s",op+1);
if(op[1]=='A'){
int x=read();
root[++n]=++sz;
sum[n]=sum[n-1]^x;
insert(n,23,root[n-1],root[n]);
}else{
int l=read(),r=read(),x=read();
printf("%d\n",ask(root[r-1],x^sum[n],23,l-1));
}
}
return 0;
}