鏈接
解法:字典樹
處理前綴異或和和後綴異或和,然後枚舉分離位置,分別查詢前綴異或最大和後綴異或最大,相加即可。(注意預處理)
代碼
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct Trie{
int root,tot,son[12800001][2];
Trie():root(1),tot(1){memset(son,0,sizeof(son));}
void insert(int x){
int u=root,b[31];for(int i=0;i<31;++i)b[i]=(x&(1<<i))>>i;
for(int i=30;~i;--i){int &v=son[u][b[i]];if(!v)v=++tot;u=v;}
}
int query(int u,int x,int p){
if(p==-1)return x;
if(son[u][1]&&(x^(1<<p))>x)return query(son[u][1],x^(1<<p),p-1);
else if(son[u][0])return query(son[u][0],x,p-1);else return query(son[u][1],x^(1<<p),p-1);
}
};
Trie t1,t2;
int max1[400001],max2[400002],n,a[400001],ans;
int main(){
scanf("%d",&n);t1.insert(0),t2.insert(0);
for(int i=1;i<=n;++i)scanf("%d",a+i);
for(int i=1,sum=0;i<=n;++i)sum^=a[i],t1.insert(sum),max1[i]=max(max1[i-1],t1.query(t1.root,sum,30));
for(int i=n,sum=0;i;--i)sum^=a[i],t2.insert(sum),max2[i]=max(max2[i+1],t2.query(t2.root,sum,30));
for(int i=0;i<=n;++i)ans=max(ans,max1[i]+max2[i+1]);
printf("%d",ans);
}