这题实际上就是加强版的LOJ10050
由于异或一个数偶数次等于啥也没干,所以异或是可以构造“前缀异或”的
那么固定一个终点
i
i
,则我们就是类似“最大连续子段和”一样要找一个^
Sj)
S
j
)
——这不就是LOJ10050吗!!!
开两个数组L(从左往右),R(从右往左)记录最优解,传递,更新答案即可
O(N∗30)
O
(
N
∗
30
)
#include<bits/stdc++.h>
#define gt() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++)
#define __R register
using namespace std;
static char buf[1000000],*p1=buf,*p2=buf;
const int maxn=(4e5)+5,L=30;
int n,Ans,a[maxn],Pow[maxn],S,fL[maxn],fR[maxn];
struct Trie{
int tot,s[maxn*L][3];bool p[L+5];
void insert(int& A,int x){
__R int rot=0,rot1=0,rot2=0,now=0;
for(__R int i=L-1;i>=0;i--) rot=s[rot][p[i]=(x>>i)&1]=s[rot][p[i]]?s[rot][p[i]]:++tot;
for(__R int i=L-1;i>=0;i--){
rot1=s[rot1][p[i]];
if(s[rot2][!p[i]]) now|=Pow[i],rot2=s[rot2][!p[i]];else rot2=s[rot2][p[i]];
if(now+Pow[i]-1<=A) return;
}
A=now;
}
}T1,T2;
int read(){
int ret=0;char ch=gt();
while(ch<'0'||ch>'9') ch=gt();
while(ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=gt();
return ret;
}
int main(){
n=read(),Pow[0]=1;
for(__R int i=1;i<L;i++) Pow[i]=Pow[i-1]<<1;
T1.insert(fL[0],S=0);for(__R int i=1;i<=n;i++) fL[i]=fL[i-1],T1.insert(fL[i],S^=(a[i]=read()));
T2.insert(fR[n+1],S=0);for(__R int i=n;i;i--){fR[i]=fR[i+1],T2.insert(fR[i],S^=a[i]);if(i>1&&fL[i-1]+fR[i]>Ans) Ans=fL[i-1]+fR[i];}
printf("%d\n",Ans);
return 0;
}