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 ",query(root[l-1],root[r],(b[n]^x))); } } return 0; }