TMD我怎么卡了这么久的常啊。。。。
就枚举分割点,左手一颗trie,右手一颗trie,就好了。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 400050 using namespace std; int n,a[maxn],x[maxn],root,ls[maxn*32],rs[maxn*32],tot=0; int mx[maxn],ans=0; int read() { char ch;int data=0; while (ch<'0' || ch>'9') ch=getchar(); while (ch>='0' && ch<='9') { data=data*10+ch-'0'; ch=getchar(); } return data; } int ask(int now,int val,int bit) { if (!now) return 0; int ans=0; for (int i=bit;i>=0;i--) { int nb=val&(1<<i); if (!nb) { if (rs[now]) {now=rs[now];ans+=(1<<i);} else now=ls[now]; } else { if (ls[now]) {now=ls[now];ans+=(1<<i);} else now=rs[now]; } } return ans; } void modify(int now,int val,int bit) { int pos=now; for (int i=bit;i>=0;i--) { int nb=val&(1<<i); if (!nb) {if (!ls[pos]) ls[pos]=++tot;pos=ls[pos];} else {if (!rs[pos]) rs[pos]=++tot;pos=rs[pos];} } } int main() { n=read();tot=root=1; for (int i=1;i<=n;i++) {a[i]=read();x[i]=x[i-1]^a[i];} for (int i=1;i<=n;i++) { mx[i]=max(max(x[i],mx[i-1]),ask(root,x[i],30)); modify(root,x[i],30); } for(int i=1;i<=tot;i++) ls[i]=rs[i]=0; tot=root=1; for (int i=n;i>=1;i--) { int ret=ask(root,x[i],30); ans=max(ans,ret+mx[i-1]); modify(root,x[i],30); } printf("%d\n",ans); return 0; }