ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

Description

Input

输入数据的第一行包含一个整数N,表示数组中的元素个数。
第二行包含N个整数A1,A2,…,AN。

Output

输出一行包含给定表达式可能的最大值。
 
dp求出:
对每个r1,A[l1]^A[l1+1]^...^A[r1]的最大值
对每个l2,A[l2]^A[l2+1]^...^A[r2]的最大值
对每个i,A[l1]^A[l1+1]^...^A[r1]的最大值lm[i] (r1≤i,1≤i≤n)
对每个i,A[l2]^A[l2+1]^...^A[r2]的最大值rm[i] (l2≥i,1≤i≤n)
ans=max{lm[i]+rm[i+1]} (1≤i<n)
暴力求复杂度为O(n3),预处理异或前缀和后缀和可降至O(n2)
再用trie优化取最大值的过程可达到O(32n)
#include<cstdio>
const int N=400005;
int n,ans=0;
int v[N];
int ls[N],rs[N];
int lm[N],rm[N];
struct node{
    node*ch[2];
    node(){
        ch[0]=ch[1]=0;
    }
};
node ns[64*N];
int np=0;
inline node*new_node(){
    return ns+np++;
}
struct trie{
    node*rt;
    trie(){
        rt=new_node();
    }
    void insert(int x){
        node*w=rt;
        for(int i=30;i>=0;i--){
            int a=x>>i&1;
            if(w->ch[a])w=w->ch[a];
            else w=w->ch[a]=new_node();
        }
    }
    int max(int x){
        int v=0;
        node*w=rt;
        for(int i=30;i>=0;i--){
            int a=(x>>i&1)^1;
            if(w->ch[a])w=w->ch[a],v|=a<<i;
            else w=w->ch[a^1],v|=(a^1)<<i;
        }
        return v^x;
    }
};
trie tr;
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",v+i);
        ls[i]=ls[i-1]^v[i];
    }
    for(int i=n;i>=1;i--)rs[i]=rs[i+1]^v[i];
    for(int i=1;i<n;i++){
        tr.insert(rs[i]);
        lm[i]=tr.max(rs[i+1]);
    }
    tr=trie();
    for(int i=n;i>1;i--){
        tr.insert(ls[i]);
        rm[i]=tr.max(ls[i-1]);
    }
    for(int i=2;i<n;i++){
        if(lm[i]<lm[i-1])lm[i]=lm[i-1];
    }
    for(int i=n-1;i>1;i--){
        if(rm[i]<rm[i+1])rm[i]=rm[i+1];
    }
    for(int i=1;i<n;i++){
        if(lm[i]+rm[i+1]>ans)ans=lm[i]+rm[i+1];
    }
    printf("%d",ans);
    return 0;
}

 

 
posted on 2016-02-09 16:08  nul  阅读(322)  评论(0编辑  收藏  举报