![]()
.jpg)
标签:
![]()
.jpg)
可持久化Trie树
计算异或前缀和,一段区间的异或和就转化为两个数的异或和。
然后求出1-i的最大异或和f[i]、i-n的最大异或和g[i],在可持久化Trie树上贪心即可。
然后枚举中间的分隔位置,计算答案。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define ll long long
#define maxn 400005
#define maxm 15000005
#define inf 1<<29
using namespace std;
int n,cnt,ans,mx;
int sum[maxn],rt[maxn],f[maxn],g[maxn];
int sz[maxm],a[maxm][2];
inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void insert(int x,int &y,int val,int tmp)
{
y=++cnt;sz[y]=sz[x]+1;
if (!tmp) return;
a[y][0]=a[x][0];a[y][1]=a[x][1];
int t=val&tmp?1:0;
insert(a[x][t],a[y][t],val,tmp>>1);
}
int query(int x,int y,int val,int tmp)
{
if (!tmp) return 0;
int t=(val&tmp?1:0)^1;
if (sz[a[y][t]]>sz[a[x][t]]) return query(a[x][t],a[y][t],val,tmp>>1)+tmp;
else return query(a[x][t^1],a[y][t^1],val,tmp>>1);
}
int main()
{
n=read();
F(i,1,n) sum[i]=sum[i-1]^read();
insert(0,rt[0],0,inf);
F(i,1,n) insert(rt[i-1],rt[i],sum[i],inf);
F(i,1,n)
{
f[i]=query(0,rt[i-1],sum[i],inf);
g[i]=query(rt[i-1],rt[n],sum[i-1],inf);
}
mx=f[1];
F(i,2,n) ans=max(ans,g[i]+mx),mx=max(mx,f[i]);
printf("%d\n",ans);
return 0;
}
标签:
原文地址:http://blog.csdn.net/aarongzk/article/details/51520368