POJ:2796 Feel Good

来源:互联网 发布:银行存款怎样划算知乎 编辑:程序博客网 时间:2024/06/05 02:08
#include <iostream>#include <string.h>#include <stdlib.h>#include <math.h>#include <algorithm>#include <stdio.h>#include <queue>#include <stack>#define LL long longusing namespace std;const int INF=0x3f3f3f3f;struct Node{    int num,id;    int l,r;}node[100005];stack <Node> s;//建立栈;LL sum[100005];int main(){    int n;    while(scanf("%d",&n)!=-1)    {        memset(sum,0,sizeof(sum));        while(!s.empty())//清空栈;        s.pop();        for(int i=1;i<=n;i++)        {            scanf("%d",&node[i].num);            node[i].id=i;            sum[i]=sum[i-1]+node[i].num;//计算出前缀和方便后面计算;        }        for(int i=1;i<=n;i++)//找出以node[i]为最小值的区间的l和r;        {            node[i].l=i;//3 1 6 4 5 2            while(!s.empty())            {                if(s.top().num>node[i].num)//如果栈顶元素大于node[i].num,栈顶出栈;                {                    node[s.top().id].r=i-1;                    node[i].l=node[s.top().id].l;                    s.pop();                }                else                break;            }            s.push(node[i]);        }        while(!s.empty())        {            node[s.top().id].r=n;            s.pop();        }        LL ans=-1;        LL temp;        int l,r;        for(int i=1;i<=n;i++)        {            temp=(sum[node[i].r]-sum[node[i].l-1])*node[i].num;            if(temp>ans)            {                ans=temp;                l=node[i].l;                r=node[i].r;            }        }        printf("%lld\n%d %d\n",ans,l,r);    }    return 0;}//建立一个单调递增栈//当元素直接进栈说明栈顶为当前栈内的最大值即向左扩展的位置就是它本身的位置//并且上一个栈顶元素找到了一个比他大的元素即可以向右扩展一位//若元素没有直接进栈说明当前元素小于栈顶元素可以继续向右扩展并直到找到一个比当前元素小的栈顶元素//此时该元素向左扩展位置就确定了//当一个元素被弹出栈时说明找到了一个比他小的元素他向右扩展的位置也就确定为该元素位置减一