3166: [Heoi2013]Alo
Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1227 Solved: 569
[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
9 2 1 4 7
Sample Output
14
HINT
【样例解释】
选择区间[1,5],最大值为 7 xor 9。
对于 100%的数据有 1 ≤ n ≤ 50000, 0 ≤ ai ≤ 10^9
Source
题解:这里看到了xor那么就要去想按位,因为xor与各个位之间是没有关联的。
就是每个宝石,可以操作的区间是知道的,除非它就是最大,否则找到左,右比它大的,然后
比如l和r,在l-r的可持久化字典树中去找即可。
好像有点麻烦,找区间的时候,是需要从大到小加入值,这样的话是可以找的。
1 #pragma GCC optimize(2)
2 #pragma G++ optimize(2)
3 #include<iostream>
4 #include<algorithm>
5 #include<cmath>
6 #include<cstdio>
7 #include<cstring>
8 #include<set>
9 #include<cstdlib>
10
11 #define guide set<int>::iterator
12 #define N 50007
13 #define inf 1000000007
14 using namespace std;
15 inline int read()
16 {
17 int x=0,f=1;char ch=getchar();
18 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
19 while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
20 return x*f;
21 }
22
23 int n;
24 int bin[37];
25 int ans,rt[N];
26 struct Node
27 {
28 int val,pos;
29 }a[N];
30 set<int>q;
31
32
33 struct trie
34 {
35 int cnt;
36 int ch[37*N][2],sum[37*N];
37 trie(){cnt=0;}
38 int insert(int x,int val)
39 {
40 int root,y;root=y=++cnt;
41 for (int i=30;i>=0;i--)
42 {
43 int t=val&bin[i];t>>=i;
44 ch[y][0]=ch[x][0],ch[y][1]=ch[x][1];
45 x=ch[x][t],y=ch[y][t]=++cnt;
46 sum[y]=sum[x]+1;
47 }
48 return root;
49 }
50 int query(int val,int yl,int xz)
51 {
52 int res=0;
53 for (int i=30;i>=0;i--)
54 {
55 int t=val&bin[i];t>>=i;
56 if(sum[ch[xz][t^1]]-sum[ch[yl][t^1]])res+=bin[i],xz=ch[xz][t^1],yl=ch[yl][t^1];
57 else xz=ch[xz][t],yl=ch[yl][t];
58 }
59 return res;
60 }
61 }trie;
62 bool operator<(Node x,Node y){return x.val>y.val;}
63 int main()
64 {
65 bin[0]=1;for(int i=1;i<=30;i++)bin[i]=bin[i-1]<<1;
66 n=read();
67 for (int i=1;i<=n;i++)
68 a[i].val=read(),a[i].pos=i;
69 for (int i=1;i<=n;i++)
70 rt[i]=trie.insert(rt[i-1],a[i].val);
71 q.insert(-1),q.insert(inf),q.insert(-2),q.insert(inf+1);//因为是次小
72 sort(a+1,a+n+1),q.insert(a[1].pos);
73 for (int i=2;i<=n;i++)
74 {
75 int l=a[i].pos,r=a[i].pos,x=a[i].pos;
76 guide p,t;
77 p=t=q.upper_bound(x);
78 r=*t;t++;r=*t-1;
79 l=*--p;p--;l=*p+1;
80 l=max(1,l),r=min(n,r);
81 if(l!=r)ans=max(ans,trie.query(a[i].val,rt[l-1],rt[r]));
82 q.insert(x);
83 }
84 printf("%d",ans);
85 }
来源:http://www.cnblogs.com/fengzhiyuan/p/8486854.html