BZOJ4260: Codechef REBXOR
Description
Input
输入数据的第一行包含一个整数N,表示数组中的元素个数。
第二行包含N个整数A1,A2,…,AN。
Output
输出一行包含给定表达式可能的最大值。
Sample Input
5
1 2 3 1 2
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。
扫一遍用Trie树算一下前缀最大异或和,后缀最大异或和。
#include<cstdio> #include<cctype> #include<queue> #include<cmath> #include<cstring> #include<algorithm> #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define ren for(int i=first[x];i;i=next[i]) using namespace std; const int BufferSize=1<<16; char buffer[BufferSize],*head,*tail; inline char Getchar() { if(head==tail) { int l=fread(buffer,1,BufferSize,stdin); tail=(head=buffer)+l; } return *head++; } inline int read() { int x=0,f=1;char c=Getchar(); for(;!isdigit(c);c=Getchar()) if(c=='-') f=-1; for(;isdigit(c);c=Getchar()) x=x*10+c-'0'; return x*f; } const int maxn=400010; const int maxnode=10000010; int A[maxn],ch[maxnode][2],ToT; void insert(int val) { int j=0; dwn(i,30,0) { int c=val>>i&1; if(!ch[j][c]) ch[j][c]=++ToT; j=ch[j][c]; } } int query(int val) { int ans=0,j=0; dwn(i,30,0) { int c=val>>i&1; if(ch[j][c^1]) j=ch[j][c^1],ans|=1<<i; else j=ch[j][c]; } return ans; } typedef long long ll; int S[maxn],f[maxn],g[maxn]; int main() { int n=read(); rep(i,1,n) A[i]=read(); rep(i,1,n) insert(S[i-1]),f[i]=max(f[i-1],query(S[i]=S[i-1]^A[i])); memset(ch,0,sizeof(ch));ToT=0; dwn(i,n,1) insert(S[i+1]),g[i]=max(g[i+1],query(S[i]=S[i+1]^A[i])); ll ans=0; rep(i,1,n-1) ans=max(ans,(ll)f[i]+g[i+1]); printf("%lld\n",ans); return 0; }