【单调栈】Vijos P1926 紫色的手链

题目链接:

  https://vijos.org/p/1926

题目大意

  给n个数(n<=100 000),求任意区间的最大值异或次大值的最大值。

题目思路:

  【模拟】【单调栈】

  我们维护一个严格单调递减队列,存放当前的数字,初始为前两个数字。

  每当加入新的元素时,依次与栈头的元素比较,每次比较更新ans(当作该元素与栈头元素构成的区间解,因为是严格单调递减序列,所以这两个元素是最大和次大的,否则栈头已经被弹出),如果新的元素比栈头元素大,就将栈头元素弹出,重复以上的比较,更新解,弹出栈头操作,直到结束。因为每个数字只会进栈出栈一次,所以时间复杂度是O(n)。

 (说得有点拙计,如果没看懂可以自己稍微画画样例什么的,或者留言~) 

 

 1 //
 2 //by coolxxx
 3 //
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<string>
 7 #include<iomanip>
 8 #include<memory.h>
 9 #include<time.h>
10 #include<stdio.h>
11 #include<stdlib.h>
12 #include<string.h>
13 #include<stdbool.h>
14 #include<math.h>
15 #define min(a,b) ((a)<(b)?(a):(b))
16 #define max(a,b) ((a)>(b)?(a):(b))
17 #define abs(a) ((a)>0?(a):(-(a)))
18 #define lowbit(a) (a&(-a))
19 #define sqr(a) (a)*(a)
20 #define swap(a,b) (a)^=(b),(b)^=(a),(a)^=(b)
21 #define eps 1e-8
22 #define MAX 0x7f7f7f7f
23 #define INF 20000
24 #define PI 3.1415926535897
25 #define N 100004
26 using namespace std;
27 int n,m,lll,ans,cas;
28 int a[N];
29 int main()
30 {
31     #ifndef ONLINE_JUDGE
32 //    freopen("1.txt","r",stdin);
33 //    freopen("2.txt","w",stdout);
34     #endif
35     int i,j,k;
36     while(~scanf("%d",&n) && n)
37     {
38         scanf("%d%d",&a[1],&a[2]);
39         lll=2;ans=a[1]^a[2];
40         for(i=3;i<=n;i++)
41         {
42             scanf("%d",&k);
43             while(lll>0 && k>a[lll])j=a[lll--]^k,ans=max(ans,j);
44             if(lll>0)ans=max(ans,a[lll]^k);
45             a[++lll]=k;
46         }
47         printf("%d\n",ans);
48     }
49     return 0;
50 }
51 
52 
53 /*
54 //
55 
56 //
57 */
View Code

 

posted @ 2016-04-01 00:54  Cool639zhu  阅读(445)  评论(0编辑  收藏  举报