Poj 2796 单调栈

关于单调栈的性质,和单调队列基本相同,只不过单调栈只使用数组的尾部, 类似于栈。

Accepted Code:

 1 /*************************************************************************
 2     > File Name: 2796.cpp
 3     > Author: Stomach_ache
 4     > Mail: [email protected]
 5     > Created Time: 2014年07月21日 星期一 22时45分56秒
 6     > Propose:
 7  ************************************************************************/
 8 #include <cmath>
 9 #include <string>
10 #include <cstdio>
11 #include <fstream>
12 #include <cstring>
13 #include <iostream>
14 #include <algorithm>
15 using namespace std;
16
17 typedef long long LL;
18 const int maxn = 100005;
19 int n;
20 // b[i] holds the smallest index where a[b[i]]...a[i] are not larger than a[i], and e[i] is similar, just extends to the right of a[i]
21 int a[maxn], b[maxn], e[maxn], st[maxn];
22 LL sum[maxn]; //prefix sum
23
24 int
25 main(void) {
26 #ifndef ONLINE_JUDGE
27       freopen("in.txt", "r", stdin);
28 #endif
29       while (~scanf("%d", &n)) {
30           for (int i = 1; i <= n; i++) scanf("%d", a+i);
31         for (int i = 1; i <= n; i++) b[i] = e[i] = i;
32         sum[0] = 0;
33         for (int i = 1; i <= n; i++) {
34             sum[i] = sum[i-1] + a[i];
35         }
36         // the top of no decreasing stack
37         int top = 0;
38         for (int i = 1; i <= n; i++) {
39               if (!top || a[i] > a[st[top-1]]) {
40                 // push an element to stack
41                   st[top++] = i;
42             } else {
43                   while (top > 0 && a[st[top-1]] > a[i]) {
44                       // update e[st[top-1]]
45                       e[st[top-1]] = i - 1;
46                     // update b[i]
47                     b[i] = b[st[top-1]];
48                     // pop the toppest element of stack
49                       top--;
50                 }
51                 if (!top || a[st[top-1]] != a[i]) {
52                       // push
53                       st[top++] = i;
54                 } else if(a[st[top-1] == a[i]]) {
55                       // update b[i]
56                       b[i] = b[st[top-1]];
57                 }
58             }
59         }
60         // update e[i] of those elements that still in the stack
61         for (int i = 0; i < top; i++) e[st[i]] = n;
62         // find the answer
63         LL ans = -1, bb, ee;
64         for (int i = 1; i <= n; i++) {
65               if (ans < a[i] * (sum[e[i]]-sum[b[i]-1])) {
66                   ans = a[i] * (sum[e[i]]-sum[b[i]-1]);
67                 bb = b[i];
68                 ee = e[i];
69             }
70         }
71         printf("%lld\n%lld %lld\n", ans, bb, ee);
72     }
73
74     return 0;
75 }

Poj 2796 单调栈

时间: 2024-09-30 15:21:21

Poj 2796 单调栈的相关文章

[poj 2796]单调栈

题目链接:http://poj.org/problem?id=2796 单调栈可以O(n)得到以每个位置为最小值,向左右最多扩展到哪里. #include<cstdio> #include<algorithm> #include<stack> using namespace std; const int maxn=100005; int a[maxn]; int l[maxn]; int r[maxn]; long long pre[maxn]; stack< p

poj 2059 单调栈

题意:求柱状图中最大矩形面积. 单调栈:顾名思义就是栈内元素单调递增的栈. 每次插入数据来维护这个栈,假设当前须要插入的数据小于栈顶的元素,那就一直弹出栈顶的元素.直到满足当前须要插入的元素大于栈顶元素为止.能够easy求出某个数左边或右边,第一个大于或小于它的数,且复杂度是O(n). 思路:easy先想到一个好的枚举方式:以当前柱状为扩展点,往左边和右边扩展.当遇到一个比当前柱状小的柱状时停止扩展.以当前柱状的高度为矩形的高.向左右扩展的距离之差为矩形的长度,这样对n个柱状进行扫描之后可得最大

POJ - 2559 单调栈

算是回顾吧 扫描计算时的高度是单调递减的, 最相对较高的能延伸的矩阵[全部]计算完以后都合并成一个待计算的相对较矮的单一矩阵 规定合并后的矩阵留到下一次计算 一直扫描到栈空(哨兵h[n+1]==0处)即可 STL炒鸡好用干嘛要手写啊 /*H E A D*/ int main(){ int n,h[maxn],w[maxn]; stack<int> stk; while(~iin(n)){ if(n==0)break; rep(i,1,n) h[i]=read(); while(!stk.emp

POJ 2796 Feel Good(单调栈)

题目地址:POJ 2796 单调栈的第一题就是这道..把我弄的晕头转向.现在终于明白了,对单调栈又加深了理解.原来单调栈不只是可以维护数. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctype.h> #incl

【POJ】2796:Feel Good【单调栈】

Feel Good Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 18449   Accepted: 5125 Case Time Limit: 1000MS   Special Judge Description Bill is developing a new mathematical theory for human emotions. His recent investigations are dedicated

51nod 1215 数组的宽度&amp;poj 2796 Feel Good(单调栈)

单调栈求每个数在哪些区间是最值的经典操作. 把数一个一个丢进单调栈,弹出的时候[st[top-1]+1,i-1]这段区间就是弹出的数为最值的区间. poj2796 弹出的时候更新答案即可 #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> #include<cmath

poj 2796 Feel Good (单调栈)

Feel Good Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 9778   Accepted: 2652 Case Time Limit: 1000MS   Special Judge Description Bill is developing a new mathematical theory for human emotions. His recent investigations are dedicated

poj 2796 Feel Good(单调栈)

Feel Good Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 11148   Accepted: 3059 Case Time Limit: 1000MS   Special Judge Description Bill is developing a new mathematical theory for human emotions. His recent investigations are dedicated

POJ 3415 Common Substrings(后缀数组+单调栈)

[题目链接] http://poj.org/problem?id=3415 [题目大意] 求出两个字符串长度大于k的公共子串的数目. [题解] 首先,很容易想到O(n2)的算法,将A串和B串加拼接符相连, 做一遍后缀数组,把分别属于A和B的所有后缀匹配,LCP-k+1就是对答案的贡献, 但是在这个基础上该如何优化呢. 我们可以发现按照sa的顺序下来,每个后缀和前面的串的LCP就是区间LCP的最小值, 那么我们维护一个单调栈,将所有单调递减的LCP值合并, 保存数量和长度,对每个属于B串的后缀更新