Trie模板题。求出每个前缀和后缀的最大异或和区间,枚举断点就可。不知为何跑得飞快。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 5 using namespace std; 6 7 const int N=400010,M=N*30; 8 int n,nd,x,ans,a[N],pre[N],suf[N],ch[M][2]; 9 10 void ins(int k){ 11 int x=1; 12 for (int i=30; ~i; i--){ 13 if (!ch[x][(k>>i)&1]) ch[x][(k>>i)&1]=++nd; 14 x=ch[x][(k>>i)&1]; 15 } 16 } 17 18 int que(int k){ 19 int x=1,res=0; 20 for (int i=30; ~i; i--) 21 if (ch[x][!((k>>i)&1)]) res|=1<<i,x=ch[x][!((k>>1)&1)]; 22 else x=ch[x][(k>>i)&1]; 23 return res; 24 } 25 26 int main(){ 27 freopen("bzoj4260.in","r",stdin); 28 freopen("bzoj4260.out","w",stdout); 29 scanf("%d",&n); nd=1; ins(0); 30 rep(i,1,n) scanf("%d",&a[i]); 31 rep(i,1,n-1) x^=a[i],pre[i]=max(pre[i-1],que(x)),ins(x); 32 memset(ch,0,sizeof(ch)); nd=1; ins(0); x=0; 33 for (int i=n; i>1; i--) x^=a[i],suf[i]=max(suf[i+1],que(x)),ins(x); 34 rep(i,1,n-1) ans=max(ans,pre[i]+suf[i+1]); 35 printf("%d ",ans); 36 return 0; 37 }