首页 > 其他 > 详细

单调栈应用

时间:2018-07-17 22:52:57      阅读:226      评论:0      收藏:0      [点我收藏+]
 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("\n");
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\tR[%d]=%d\n",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\n",ans);
76     printf("%d %d\n",l,r);
77     return 0;
78 }

 

单调栈应用

原文:https://www.cnblogs.com/LeeSongt/p/9326323.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!