BZOJ4260: Codechef REBXOR

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。

 

扫一遍用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;
}
View Code

 

你可能感兴趣的:(BZOJ4260: Codechef REBXOR)