bzoj4260 Codechef REBXOR

4260: Codechef REBXOR

Time Limit: 10 Sec   Memory Limit: 256 MB
Submit: 446   Solved: 196
[ Submit][ Status][ Discuss]

Description

Input

输入数据的第一行包含一个整数N,表示数组中的元素个数。
第二行包含N个整数A1,A2,…,AN。

Output

输出一行包含给定表达式可能的最大值。

Sample Input

5
1 2 3 1 2

Sample Output

6

HINT

满足条件的(l1,r1,l2,r2)有:(1,2,3,3),(1,2,4,5),(3,3,4,5)。

对于100%的数据,2 ≤ N ≤ 4*105,0 ≤ Ai ≤ 109。

Source

By yts1999




可持久化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;
}


你可能感兴趣的:(bzoj,可持久化Trie树)