Codechef REBXOR(01Trie)

01Trie mu版题

emmmmm

题目(手打)
一个序列A,求两个不相交的区间,使得异或和之和最大
对于100%的数据,2<=N<= 4105 ,0<=Ai<= 109

#include <stdio.h>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
const int N = 400005;
inline int max(int x,int y){
    int m=x-y>>31;
    return y&m|x&~m;
}
int n, a[N], l[N], r[N], son[30000000][2];
int L[N], R[N], root = 1, cnt;

struct Dic{
    void init(){ memset( son, 0, sizeof( son ) ); }
    void ins( int x ){
        register int i, p = root, t;
        for( i = 30; i >= 0; i -- ){
            t = ( x & 1 << i ) ? 1 : 0;
            if( ! son[p][t] ) son[p][t] = ++cnt;
            p = son[p][t];
        }
    }
    int cal( int x ){
        register int i, p = root, t, ans = 0;
        for( i = 30; i >= 0; i -- ){
            t = ( x & 1 << i ) ? 1 : 0;
            if( son[p][t^1] ) p = son[p][t^1], ans |= 1 << i;
            else p = son[p][t];
        }
        return ans;
    }
}Trie;



int main()
{
    scanf("%d",&n);
    register int i, ans = 0;
    cnt = 1;
    Trie.ins( 0 );
    for( i = 1; i <= n; i ++ ){
        scanf("%d",&a[i]);
        l[i] = a[i] ^ l[i-1];
        Trie.ins( l[i] );
        L[i] = max( L[i-1], Trie.cal( l[i] ) );
    }
    Trie.init();
    cnt = 1;
    Trie.ins( 0 );
    for( i = n; i; i -- ){
        r[i] = a[i] ^ r[i+1];
        Trie.ins( r[i] );
        R[i] = max( R[i+1], Trie.cal( r[i] ) );
    }
    for( i = 1; i <= n; i ++ )
        if( ans < L[i-1] + R[i] ) ans = L[i-1] + R[i];
    printf("%d",ans);
    return 0;
}
发布了11 篇原创文章 · 获赞 5 · 访问量 3373

猜你喜欢

转载自blog.csdn.net/qq_24855707/article/details/78218666