1. 程式人生 > >BZOJ 4260 Codechef REBXOR【Trie】

BZOJ 4260 Codechef REBXOR【Trie】

字典樹上進行二進位制拆分進行字首和字尾和的處理:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define db double
#define sg string
#define make make_pair
#define pll pair<int,int>
#define rel(i,x,y) for(int i=(x);i<(y);i++)
#define rep(i,x,y) for(int i=(x);i<=(y);i++)
#define red(i,x,y) for(int i=(x);i>=(y);i--)
#define res(i,x) for(int i=head[x];i;i=nxt[i])
using namespace std;

const int N=4e5+6;
const int Inf=1e18;
const db Eps=1e-10;

int n,ans,tot,a[N],lm[N],rm[N],ch[N*32][2];

inline int read() {
	int x=0;char ch=getchar();bool f=0;
	while(ch>'9'||ch<'0'){if(ch=='-')f=1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return f?-x:x;
}

void ins(int x) {
	int cur=0;
	for(int i=1<<30;i;i>>=1) {
		int f=(x&i)?1:0;
		if(!ch[cur][f]) ch[cur][f]=++tot;
		cur=ch[cur][f];
	}
}

int getmax(int x) {
	int cur=0,ret=0;
	for(int i=1<<30;i;i>>=1) {
		int f=(x&i)?0:1;
		if(ch[cur][f]) ret+=i,cur=ch[cur][f];
		else cur=ch[cur][!f];
	}
	return ret;
}

int main() {
	n=read();
	
	rep(i,1,n) a[i]=read();
	
	int sum=0;ins(sum);
	
	rep(i,1,n) {
		sum^=a[i];
		ins(sum);
		lm[i]=max(lm[i-1],getmax(sum));
	}
	
	memset(ch,0,sizeof(ch));
	
	sum=0;ins(sum);
	
	red(i,n,1) {
		sum^=a[i];
		ins(sum);
		rm[i]=max(rm[i+1],getmax(sum));
	}
	
	rep(i,0,n) ans=max(ans,lm[i]+rm[i+1]);
	
	printf("%d\n",ans);

	return 0;
}