http://www.lydsy.com/JudgeOnline/problem.php?id=3261
可持久化Tire+异或前缀和+贪心
可持久化Tire表示二进制数其实就是可持久化的值域线段树
每次贪心地构造最优解
#include<cstdio>
#define FOR(i,s,t) for(register int i=s;i<=t;++i)
const int NlogN=16000011,N=1000011;
int tot;
namespace Tire_Tree{
struct Tire{
int to[2];
int sum;
}tr[NlogN];
int root[N];
inline void insert(int cpy,int &now,int v,int dep){
tr[now=++tot]=tr[cpy];
++tr[now].sum;
if(dep==-1)return;
int t=(v>>dep)&1;
insert(tr[cpy].to[t],tr[now].to[t],v,dep-1);
}
inline int query(int l,int r,int v){
int t,ans=0;
for(register int i=23;~i;--i){
t=((v>>i)&1)^1;
if(tr[tr[r].to[t]].sum>tr[tr[l].to[t]].sum){
ans|=(1<<i);
l=tr[l].to[t];r=tr[r].to[t];
}
else{
t^=1;
l=tr[l].to[t];r=tr[r].to[t];
}
}
return ans;
}
}
using namespace Tire_Tree;
int n,m;
int a[N],b[N];
char s[5];
int l,r,x;
int main(){
scanf("%d%d",&n,&m);++n;
FOR(i,2,n)scanf("%d",a+i);
FOR(i,1,n)insert(root[i-1],root[i],b[i]=b[i-1]^a[i],23);
while(m--){
scanf("%s",s);
if(s[0]==‘A‘){
++n;
scanf("%d",a+n);
insert(root[n-1],root[n],b[n]=b[n-1]^a[n],23);
}
else{
scanf("%d%d%d",&l,&r,&x);
printf("%d\n",query(root[l-1],root[r],(b[n]^x)));
}
}
return 0;
}