BZOJ3166: [Heoi2013]Alo

3166: [Heoi2013]Alo

Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 394  Solved: 204
[Submit][Status]

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

题解:
枚举这个次小值,那么它作为最小值的区间就是左边第二个比它大的数的位置+1到右边第二个比它大的数的位置-1,这一步可以用set(我刚开始居然用的单调队列。。。)
然后可持久化trie搞就行了
代码:
  1 #include<cstdio>
  2 
  3 #include<cstdlib>
  4 
  5 #include<cmath>
  6 
  7 #include<cstring>
  8 
  9 #include<algorithm>
 10 
 11 #include<iostream>
 12 
 13 #include<vector>
 14 
 15 #include<map>
 16 
 17 #include<set>
 18 
 19 #include<queue>
 20 
 21 #include<string>
 22 
 23 #define inf 1000000000
 24 
 25 #define maxn 100000+5
 26 
 27 #define maxm 2000000+5
 28 
 29 #define eps 1e-10
 30 
 31 #define ll long long
 32 
 33 #define pa pair<int,int>
 34 
 35 #define for0(i,n) for(int i=0;i<=(n);i++)
 36 
 37 #define for1(i,n) for(int i=1;i<=(n);i++)
 38 
 39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
 40 
 41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
 42 
 43 #define mod 1000000007
 44 
 45 using namespace std;
 46 
 47 inline int read()
 48 
 49 {
 50 
 51     int x=0,f=1;char ch=getchar();
 52 
 53     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 54 
 55     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
 56 
 57     return x*f;
 58 
 59 }
 60 int n,mx,l[maxn],r[maxn],a[maxn],tot,sta[maxn],rt[maxn],t[maxm][2],id[maxm];
 61 pair<int,int>b[maxn];
 62 set<int>s;
 63 set<int>::iterator it;
 64 inline void insert(int pre,int x,int k)
 65 {
 66     int now=rt[k]=++tot;id[tot]=k;
 67     for3(i,30,0)
 68     {
 69         int j=(x>>i)&1;
 70         t[now][j^1]=t[pre][j^1];
 71         t[now][j]=++tot;id[tot]=k;
 72         now=tot;
 73         pre=t[pre][j];
 74     }
 75 }
 76 inline int query(int l,int r,int x)
 77 {
 78     int now=rt[r],ret=0;
 79     for3(i,30,0)
 80     {
 81         int j=((x>>i)&1)^1;
 82         if(id[t[now][j]]>=l)ret|=1<<i;else j^=1;
 83         now=t[now][j];
 84     }
 85     return ret;
 86 }
 87 inline int getl(int x)
 88 {
 89     it=s.find(x);
 90     if(it--==s.begin())return 0;
 91     if(it--==s.begin())return 0;
 92     return *it;
 93 }
 94 inline int getr(int x)
 95 {
 96     it=s.find(x);
 97     if(++it==s.end())return n+1;
 98     if(++it==s.end())return n+1;
 99     return *it;
100 }
101 
102 int main()
103 
104 {
105 
106     freopen("input.txt","r",stdin);
107 
108     freopen("output.txt","w",stdout);
109     n=read();id[0]=-1;
110     insert(rt[0],0,0);
111     for1(i,n)
112     {
113         a[i]=read();insert(rt[i-1],a[i],i);mx=max(mx,a[i]);
114         b[i].first=a[i];b[i].second=i;
115     }
116     sort(b+1,b+n+1);
117     for3(i,n,1)
118     {
119         s.insert(b[i].second);
120         l[b[i].second]=getl(b[i].second);
121         r[b[i].second]=getr(b[i].second);
122     }
123     int ans=0;
124     for1(i,n)if(a[i]!=mx)ans=max(ans,query(l[i]+1,r[i]-1,a[i]));
125     printf("%d\n",ans);
126 
127     return 0;
128 
129 }  
View Code

 

posted @ 2014-12-05 11:24  ZYF-ZYF  Views(253)  Comments(0Edit  收藏  举报