1. 程式人生 > >Bzoj 3166 [Heoi2013] Alo 題解

Bzoj 3166 [Heoi2013] Alo 題解

cst 理解 不同 2個 個數 操作 led search 數學

3166: [Heoi2013]Alo

Time Limit: 20 Sec Memory Limit: 256 MB
Submit: 1118 Solved: 518
[Submit][Status][Discuss]

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

HINT

【樣例解釋】

選擇區間[1,5],最大值為 7 xor 9。
對於 100%的數據有 1 ≤ n ≤ 50000, 0 ≤ ai ≤ 10^9

Source

加強型數據By Hta

  又是一道大坑啊……

  習慣了求區間最大值,區間次大值怎麽求呢?本題的n並不允許我們枚舉區間,因此我們需要去求出每一個點的可選範圍。既然該點是作為次大值出現在區間裏,那麽我們就要保證區間裏有且只有一個比他大的。那麽,他的取值範圍就是他向左數第2個比他大的數+1~他向右數第2個比他大的數-1。當時看黃學長的時候黃學長說“前驅的前驅”腦子沒反應過來,還以為是對他的前驅而言的前驅……

  區間知道了,那麽怎麽求最大值呢?如果說這道題我們不需要求這麽多次區間異或最大值我們可以使用01trie樹進行貪心。然而,由於這裏我們要求好多次,普通的01trie並沒有什麽用,我們需要的是一個支持區間求異或最大值的數據結構——可持久化01trie.

  其實可持久化01trie打起來和不帶修改的主席樹沒有太大的差別。畢竟都是二叉樹。如果沒有打過可以先去打一下主席樹的模板題,求區間第K大。

  插入操作基本不變。在查詢的時候我們利用前綴和,能讓他異或後該位為1,且在這個區間裏有滿足要求的數,我們就選上並且沿著trie樹向那個方向走,否則就向另一個方向走,可以把它理解為一個特殊的在trie樹上的dfs。

技術分享
  1 #include <iostream>
  2 #include <cstdlib>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <algorithm>
  6 #include <cmath>
  7 #include <queue>
  8 #include <set>
  9 #include <vector>
 10 #define N 50006
 11 #define lowbit(x) (x&(-x))
 12 using namespace std;
 13 int n,a[N],b[N];
 14 set<int> q;
 15 struct node{
 16     int size;
 17     node* ch[2];
 18     node() {
 19         size=0;
 20         ch[1]=ch[0]=0;
 21     }
 22 }*null=new node(),*root[N];
 23 node* newnode()
 24 {
 25     node* x=new node();
 26     x->ch[0]=x->ch[1]=null;
 27     return x;
 28 }
 29 void insert(node* la,node* now,int js,int x)
 30 {
 31     now->size=la->size+1;
 32     if(!js)return;
 33     if(x&(1ll<<(js-1)))
 34     {
 35         now->ch[0]=la->ch[0];
 36         now->ch[1]=newnode();
 37         insert(la->ch[1],now->ch[1],js-1,x);
 38     }
 39     else
 40     {
 41         now->ch[1]=la->ch[1];
 42         now->ch[0]=newnode();
 43         insert(la->ch[0],now->ch[0],js-1,x);  
 44     }
 45 }
 46 long long que(node* l,node* r,int x)
 47 {
 48     long long ans=0;
 49     for(int i=32;i>=1;i--)
 50     {
 51         if(x&(1ll<<(i-1)))
 52         {
 53             if(r->ch[0]->size-l->ch[0]->size)
 54             {
 55                 ans|=(1ll<<(i-1));
 56                 l=l->ch[0];
 57                 r=r->ch[0];
 58             }
 59             else
 60             {
 61                 r=r->ch[1];
 62                 l=l->ch[1];
 63             }
 64         }
 65         else
 66         {
 67             if(r->ch[1]->size-l->ch[1]->size) 
 68             {
 69                 ans|=(1ll<<(i-1));
 70                 l=l->ch[1];
 71                 r=r->ch[1];
 72             }
 73             else
 74             {
 75                 r=r->ch[0];
 76                 l=l->ch[0];
 77             }
 78         }
 79     }
 80     return ans;
 81 }
 82 bool px(int x,int y)
 83 {
 84     return a[x]>a[y];
 85 }
 86 int main()
 87 {
 88     null->ch[0]=null->ch[1]=null;
 89     root[0]=newnode();
 90     scanf("%d",&n);
 91     for(int i=1;i<=n;i++)
 92     {
 93         root[i]=newnode();
 94         scanf("%d",&a[i]);
 95         insert(root[i-1],root[i],32,a[i]);
 96         b[i]=i;
 97     }
 98     sort(b+1,b+n+1,px);
 99     long long ans=0;
100     q.insert(-2);q.insert(-1);
101     q.insert(1000000002);q.insert(1000000003);
102     q.insert(b[1]);
103     for(int i=2;i<=n;i++)
104     {
105         set<int>::iterator it,p;
106         p=it=q.lower_bound(b[i]);
107         int r,l;
108         it++;r=*it-1;
109         p--;p--; l=*p+1;
110         l=max(l,1);r=min(r,n);
111         if(l!=r)ans=max(ans,que(root[l-1],root[r],a[b[i]]));
112         q.insert(b[i]); 
113     }
114     printf("%lld\n",ans);
115     return 0;
116 }
View Code

Bzoj 3166 [Heoi2013] Alo 題解