Gym - 101334F 单调栈

当时我的第一想法也是用单调栈,但是被我写炸了;我也不知道错在哪里;

看了大神的写法,用数组模拟的;

记录下单调递增栈的下标,以及每个数字作为最小值的最左边的位置。

当有数据要出栈的时候,说明栈里的数据已经不是最小了,右端点就是当前位置-1,那么就可以计算栈顶的元素所作的贡献;出栈完后,当前这个数字,他的最左边就是栈顶所能到达的位置;入栈;

#include <bits/stdc++.h>

using namespace std;

const int maxn = 100000 + 5;
int a[maxn];
int stacks[maxn];
long long sum[maxn];
int lef[maxn];

int main()
{
    freopen("feelgood.in","r",stdin);
    freopen("feelgood.out","w",stdout);
    int n;
    scanf("%d",&n);

    memset(sum,0,sizeof(sum));
    memset(lef,0,sizeof(lef));

    for(int i=1;i<=n;i++) {
        scanf("%d",&a[i]);
        sum[i] = sum[i-1] + a[i];
    }

    a[++n] = -1;
    int top = 0;
    long long ans = -1;
    int ansl = 0,ansr = 0;
    for(int i=1;i<=n;i++) {
        if(top==0||a[i]>a[stacks[top-1]]) {
            stacks[top++] = i;
            lef[i] = i;
            continue;
        }
        if(a[i]==a[stacks[top-1]])
            continue;
        while(top>=1&&a[i]<a[stacks[top-1]]) {
            top --;
            long long tmp = (long long)a[stacks[top]]*(sum[i-1]-sum[lef[stacks[top]]-1]);
            if(tmp>ans) {
                ansr = i-1;
                ansl = lef[stacks[top]];
                ans = tmp;
            }
        }

        lef[i] = lef[stacks[top]];
        stacks[top++] = i;


    }

    printf("%lld\n%d %d\n",ans,ansl,ansr);

    return 0;
}
View Code

相关文章: