Codechef REBXOR

Read problems statements in Mandarin and Russian. Translations in Vietnamese to be uploaded soon.

Nikitosh the painter has a 1-indexed array A of N elements. He wants to find the maximum value of expression 

(A[l1] ⊕ A[l1 + 1] ⊕ ... ⊕ A[r1]) + (A[l2] ⊕ A[l2 + 1] ⊕ ... ⊕ A[r2]) where 1 ≤ l1 ≤ r1 < l2 ≤ r2 ≤ N.

Here, x ⊕ y means the bitwise XOR of x and y.

Because Nikitosh is a painter and not a mathematician, you need to help him in this task.

Input

The first line contains one integer N, denoting the number of elements in the array.

The second line contains N space-separated integers, denoting A1A2, ... , AN.

Output

Output a single integer denoting the maximum possible value of the given expression.

Constraints

  • 2 ≤ N ≤ 4*105
  • 0 ≤ Ai ≤ 109

Subtasks

  • Subtask 1 (40 points) : 2 ≤ N ≤ 104
  • Subtask 2 (60 points) : Original constraints

Example

Input:
5
1 2 3 1 2

Output:
6

Explanation

Choose (l1r1l2r2) = (1, 2, 3, 3) or (1, 2, 4, 5) or (3, 3, 4, 5).

很久之前做的一道Trie树搞异或的题啦。。。。

大致就是求一下前缀和后缀异或最大值然后更新答案就好了。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
#define ll int
#define maxn 400005
using namespace std;
 
long long ans=0;
ll ci[35];
struct Trie{
    ll ch[maxn*20][2];
    ll tot,rot;
     
    void ins(ll x){
        ll now=rot;
        for(int i=30;i>=0;i--){
            ll c=(ci[i]&x)?1:0;
            if(!ch[now][c]) ch[now][c]=++tot;
            now=ch[now][c];
        }
    }
     
    ll find_max(ll x){
        ll now=rot,alr=0;
        for(int i=30;i>=0;i--){
            ll c=(ci[i]&x)?1:0;
            if(ch[now][c^1]) alr+=ci[i],now=ch[now][c^1];
            else now=ch[now][c];
        }
        return alr;
    }
}tr;
 
ll a[maxn],w[maxn],n;
ll lef[maxn],rig[maxn];
 
inline void init(){
    ci[0]=1;
    for(int i=1;i<=30;i++) ci[i]=ci[i-1]<<1;
    tr.rot=tr.tot=1;
}
 
int main(){
    init();
     
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",a+i),w[i]=a[i]^w[i-1];
     
    tr.ins(0);
    for(int i=1;i<=n;i++){
        lef[i]=max(lef[i-1],tr.find_max(w[i]));
        tr.ins(w[i]);
    }
     
    memset(tr.ch,0,sizeof(tr.ch));
    init();
     
    for(int i=n;i;i--){
        rig[i]=max(rig[i+1],tr.find_max(w[i]));
        tr.ins(w[i]);
    }
     
    for(int i=1;i<=n;i++) ans=max(ans,(long long)(lef[i]+rig[i]));
     
    printf("%lld
",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/JYYHH/p/8404222.html