[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< pair<int,int> > S;

int main()
{
    int n;
    while (~scanf("%d",&n))
    {
        while (!S.empty()) S.pop();
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);
        a[n+1]=-1;
        S.push(make_pair(-2,0));
        for (int i=1;i<=n+1;i++)
        {
            while (S.top().first>=a[i])
            {
                int p=S.top().second;
                S.pop();
                l[p]=S.top().second+1;
                r[p]=i-1;
            }
            S.push(make_pair(a[i],i));
        }
        pre[0]=0;
        for (int i=1;i<=n;i++) pre[i]=pre[i-1]+a[i];
        long long ans=-1;
        int ansp=-1;
        for (int i=1;i<=n;i++)
        {
            long long tt=(pre[r[i]]-pre[l[i]-1])*a[i];
            if (tt>ans)
            {
                ans=tt;
                ansp=i;
            }
        }
        printf("%lld\n%d %d\n",ans,l[ansp],r[ansp]);
    }
    return 0;
}
时间: 2024-09-29 16:12:47

[poj 2796]单调栈的相关文章

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 单调栈

关于单调栈的性质,和单调队列基本相同,只不过单调栈只使用数组的尾部, 类似于栈. Accepted Code: 1 /************************************************************************* 2 > File Name: 2796.cpp 3 > Author: Stomach_ache 4 > Mail: [email protected] 5 > Created Time: 2014年07月21日 星期一

【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串的后缀更新