首页 > 代码库 > [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< 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;
}

 

[poj 2796]单调栈