BZOJ 3166 可持久化Trie

Description

Welcome to ALO ( Arithmetic and Logistic Online)。這是一個VR MMORPG ,
如名字所見,到處充滿了數學的謎題。
現在你擁有n顆寶石,每顆寶石有一個能量密度,記爲ai,這些寶石的能量
密度兩兩不同。現在你可以選取連續的一些寶石(必須多於一個)進行融合,設爲  ai, ai+1, …, a j,則融合而成的寶石的能量密度爲這些寶石中能量密度的次大值
與其他任意一顆寶石的能量密度按位異或的值,即,設該段寶石能量密度次大值
爲k,則生成的寶石的能量密度爲max{k xor ap | ap ≠ k , i ≤ p ≤ j}。 
現在你需要知道你怎麼選取需要融合的寶石,才能使生成的寶石能量密度最大。 

Input

第一行,一個整數 n,表示寶石個數。 
第二行, n個整數,分別表示a1至an,表示每顆寶石的能量密度,保證對於i ≠ j有 ai ≠ aj。 
 

Output

輸出一行一個整數,表示最大能生成的寶石能量密度。 

Sample Input

5
9 2 1 4 7


Sample Output

14
可以枚舉次大值,那麼它能覆蓋的範圍如圖。
紅色爲枚舉到的次大值,黑色爲大於它的值,其餘爲小於它的值。
它做多能覆蓋的兩個區間如圖。
這要在這些區間中查詢即可。
對權值排序完後用set維護就好了。
#include <stdio.h>
#include <cstring>
#include <set>
#include <iostream>
#include <algorithm>
using namespace std;
const int inf = 1<<30;
const int MAXN = 50005;
int n,Ans;
std::set<int>q;
 
 
template<typename _t>
inline _t read(){
    _t x=0,f=1;
    char ch=getchar();
    for(;ch>'9'||ch<'0';ch=getchar())if(ch=='-')f=-f;
    for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+(ch^48);
    return x*f;
}
 
struct data{
    int pos,val;
    bool operator < (const data &a)const{
        return val>a.val;
    }
}a[MAXN];
 
struct Tree{
    Tree *ch[2];int s;
    void* operator new(size_t,Tree *ls,Tree *rs,int size);
}*null,*mempool,*C,*root[MAXN];
 
void* Tree :: operator new(size_t,Tree *ls,Tree *rs,int size){
    if(C==mempool){
        C=new Tree[1<<15];
        mempool=C+(1<<15);
    }
    C->ch[0]=ls;C->ch[1]=rs;C->s=size;
    return C++;
}
 
Tree* insert(Tree *old,int x,int full=inf){
    if(!full)return new(old->ch[0],old->ch[1],old->s+1)Tree;
    else if(x&full)return new(old->ch[0],insert(old->ch[1],x,full>>1),old->s+1)Tree;
    else return new(insert(old->ch[0],x,full>>1),old->ch[1],old->s+1)Tree;
}
 
int Query(Tree *old,Tree *now,int x,int full=inf){
    if(!full)return 0;
    int d = (x&full)?0:1;
    int tmp = now->ch[d]->s-old->ch[d]->s;
    if(tmp)return full|Query(old->ch[d],now->ch[d],x,full>>1);
    else return Query(old->ch[d^1],now->ch[d^1],x,full>>1);
}
 
int main(){
    n=read<int>();
    null = new(null,null,0)Tree;
    null->ch[0]=null->ch[1]=null;
    root[0]=insert(null,0);
    for(int i=1;i<=n;i++){
        a[i].val=read<int>();
        a[i].pos=i;
        root[i]=insert(root[i-1],a[i].val);
    }
    std::sort(&a[1],&a[n+1]);
    q.insert(-1);q.insert(-2);q.insert(-3);
    q.insert(n+1);q.insert(n+2);q.insert(n+3);
    q.insert(a[1].pos);
    for(int i=2;i<=n;i++){
        std::set<int>::iterator front,back;
        back=q.lower_bound(a[i].pos);front=back;
        back++;
        front--;front--;
        int l = *front+1,r=*back-1;
        l=max(l,1),r=min(r,n);
        Ans=max(Ans,Query(root[l-1],root[r],a[i].val));
        q.insert(a[i].pos);
    }
    printf("%d\n",Ans);
}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章