求出以i为结尾的前缀的最大抑或和,以i为开始的后缀最大抑或和。
然后用字典树来维护抑或出来的前缀和后缀。
似乎很水的样子
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#define T 400004
using namespace std;
int sc()
{
int i=0; char c=getchar();
while(c>'9'||c<'0')c=getchar();
while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();
return i;
}
int p[T*32][2],a[T],L[T],R[T];
int n,now,tot,ans;
void build(int x)
{
int now=0;
for(int i=1<<30;i;i>>=1)
{
int w=(x&i)?1:0;
if(p[now][w])now=p[now][w];
else now=p[now][w]=++tot;
}
}
int cal(int x)
{
int now=0,ans=0;
for(int i=1<<30;i;i>>=1)
{
int w=(x&i)?0:1;
if(p[now][w])
ans|=i,now=p[now][w];
else
now=p[now][!w];
}
return ans;
}
int main()
{
n=sc();
for(int i=1;i<=n;i++)a[i]=sc();
build(now=tot=0);
for(int i=1;i<=n;i++)
{
now^=a[i];
build(now);
L[i]=cal(now);
L[i]=max(L[i],L[i-1]);
}
memset(p,0,sizeof(p));
build(now=tot=0);
for(int i=n;i;i--)
{
now^=a[i];
build(now);
R[i]=cal(now);
R[i]=max(R[i],R[i-1]);
ans=max(ans,L[i-1]+R[i]);
}
cout<<ans;
return 0;
}