【传送门:BZOJ4260】
简要题意:
给出一个长度为n的序列
求出l1,r1,l2,r2,使得a[l1]^a[l1+1]...a[r1]+a[l2]^a[l2+1]...a[r2]最大,且1<=l1<=r1<l2<=r2<=n
题解:
01字典树,get到了字典树处理异或和的操作
只要用贪心的思想跑就好了
参考代码:
#include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> using namespace std; struct trie { int c[2]; }t[21000000];int tot; int now; void clean(int x) { t[x].c[0]=t[x].c[1]=0; } void bt(int d) { int x=0; for(int i=30;i>=0;i--) { int y=(d>>i)&1; if(t[x].c[y]==0) clean(++tot),t[x].c[y]=tot; x=t[x].c[y]; } } int lmax[410000],rmax[410000]; int a[410000]; int solve(int d) { int x=0,ans=0; for(int i=30;i>=0;i--) { int y=(d>>i)&1; if(t[x].c[y^1]!=0) ans+=1<<i,x=t[x].c[y^1]; else x=t[x].c[y]; } return ans; } int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); memset(lmax,0,sizeof(lmax)); memset(rmax,0,sizeof(rmax)); now=0;tot=0; clean(0); bt(now); for(int i=1;i<=n;i++) { now^=a[i]; bt(now); lmax[i]=max(solve(now),lmax[i-1]); } now=0;tot=0; clean(0); bt(now); for(int i=n;i>=1;i--) { now^=a[i]; bt(now); rmax[i]=max(solve(now),rmax[i-1]); } int ans=0; for(int i=0;i<=n;i++) ans=max(ans,lmax[i]+rmax[i+1]); printf("%d ",ans); return 0; }