单调栈应用

Posted leesongt

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单调栈应用相关的知识,希望对你有一定的参考价值。

 1 /*
 2   题意:POJ2796 给定一个长度为n的数组,求sum(a[i])*min(a[i)最大的一段区间。
 3   思路:枚举每个a[i],求最左边和最右边的距离。利用单调栈求左右区间
 4   时间:2018.07.17
 5 */
 6 // #include <bits/stdc++.h>
 7 #include <cstdio>
 8 #include <iostream>
 9 using namespace std;
10 
11 typedef long long LL;
12 const int MAXN=100005;
13 const LL MOD7 = 1e9+7;
14 
15 int a[MAXN];
16 int n;
17 LL sum[MAXN];
18 int L[MAXN];
19 int R[MAXN];
20 int Stack[MAXN];
21 int top;
22 
23 void printStack()
24 {
25     for (int i=0;i<top;++i) printf("%d ",Stack[i]);printf("
");
26 }
27 
28 void init()
29 {
30     top=0;
31     for (int i=1;i<=n;++i)
32     {
33         while (top && a[Stack[top-1]]>=a[i]) --top;
34         // printf("%d: ",i);
35         // printStack();
36         if (!top) L[i]=1;
37         else L[i]=Stack[top-1]+1;
38         Stack[top++]=i;
39     }
40     top=0;
41     for (int i=n;i>=1;--i)
42     {
43         while (top && a[Stack[top-1]]>a[i]) --top;
44         if (!top) R[i]=n;
45         else R[i] = Stack[top-1]-1;
46         Stack[top++]=i;
47     }
48     // for (int i=1;i<=n;++i) printf("L[%d]=%d	R[%d]=%d
",i,L[i],i,R[i]);
49 }
50 
51 int main()
52 {
53 #ifndef ONLINE_JUDGE
54     freopen("test.txt","r",stdin);
55 #endif // ONLINE_JUDGE
56     scanf("%d",&n);
57     for (int i=1;i<=n;++i)
58     {
59         scanf("%d",&a[i]);
60         sum[i]=sum[i-1]+a[i];
61     }
62     init();
63     LL ans=-1;
64     int l,r;
65     for (int i=1;i<=n;++i)
66     {
67         LL tmp = (LL)a[i]*(sum[R[i]]-sum[L[i]-1]);
68         if (tmp>ans)
69         {
70             ans = tmp;
71             l=L[i];
72             r=R[i];
73         }
74     }
75     printf("%lld
",ans);
76     printf("%d %d
",l,r);
77     return 0;
78 }

 

以上是关于单调栈应用的主要内容,如果未能解决你的问题,请参考以下文章

栈7:单调栈的原理和应用

单调栈的应用

单调栈的应用

单调栈的应用

单调栈的应用

浅谈单调栈的实现方式和简单应用