bzoj3261: 最大异或和 可持久化字典树模板
可持久化字典树不过记得是两次前缀和,所以记得减2,还有p=1的情况。
#include<bits/stdc++.h> using namespace std; int l[18000000],r[18000000],sum[18000000],ans,a[600000],root[600000],n,m,cnt=0,l2,r2,x; char s[6]; void add(int &rt,int pre,int val,int id) { if(!rt)rt=++cnt; sum[rt]=sum[pre]+1; if(id<0)return; l[rt]=l[pre];r[rt]=r[pre]; if(1<<(id)&val){r[rt]=0;add(r[rt],r[pre],val,id-1);} else {l[rt]=0;add(l[rt],l[pre],val,id-1);} } void getmaxn(int L,int R,int id,int val) { if(id<0)return; if((1<<id)&val) { if(sum[l[R]]-sum[l[L]]) { getmaxn(l[L],l[R],id-1,val); ans|=(1<<id); } else { getmaxn(r[L],r[R],id-1,val); } } else { if(sum[r[R]]-sum[r[L]]) { getmaxn(r[L],r[R],id-1,val); ans|=(1<<id); } else { getmaxn(l[L],l[R],id-1,val); } } } int main() { //freopen("xf.in","r",stdin); //freopen("xf.out","w",stdout); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){scanf("%d",&a[i]);a[i]^=a[i-1];add(root[i],root[i-1],a[i],25);} for(int i=1;i<=m;i++) { scanf("%s",s); if(s[0]=='A') { scanf("%d",&a[++n]); a[n]^=a[n-1]; add(root[n],root[n-1],a[n],25); } else { ans=0; scanf("%d%d%d",&l2,&r2,&x); getmaxn(root[max(l2-2,0)],root[r2-1],25,x^a[n]); if(l2==1)ans=max(a[n]^x,ans); printf("%d\n",ans); } } return 0; }