首页 > 其他 > 详细

Codeforces Round #622 (Div. 2) C2 - Skyscrapers (hard version) 单调栈

时间:2020-02-27 17:14:51      阅读:76      评论:0      收藏:0      [点我收藏+]

从左往右扫,找到比第i个小的第一个数字,l[i] = l[last] + (i - last) * m[i],用单调栈O(n)维护这个过程,再从右往左扫,同理可以算出r数组,注意一下long long

#include <bits/stdc++.h>
using namespace std;
const int N = 5000010;
int m[N], ans[N];
long long l[N], r[N];
stack < int > s;
int main() {
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &m[i]);
        while (!s.empty() && m[s.top()] > m[i]) {
            s.pop();
        }
        if (s.empty())    l[i] = 1ll * i * m[i];
        else    l[i] = l[s.top()] + 1ll * (i - s.top()) * m[i];
        s.push(i); 
    }
    while (!s.empty())    s.pop();
    for (int i = n; i >= 1; i--) {
        while (!s.empty() && m[s.top()] > m[i]) {
            s.pop();
        }
        if (s.empty())    r[i] = 1ll * (n - i + 1) * m[i];
        else    r[i] = r[s.top()] + 1ll * (s.top() - i) * m[i];
        s.push(i); 
    }
    long long t = 0;
    int peak = 0;
    for (int i = 1; i <= n; i++) {
        long long tot = l[i] + r[i] - m[i];
        if (tot > t)
            peak = i, t = tot;
    }
    ans[peak] = m[peak];
    for (int i = peak - 1; i >= 1; i--)
        ans[i] = min(ans[i + 1], m[i]);
    for (int i = peak + 1; i <= n; i++)
        ans[i] = min(ans[i - 1], m[i]);
    for (int i = 1; i <= n; i++)
        printf("%d ", ans[i]);
    return 0;
}

 

Codeforces Round #622 (Div. 2) C2 - Skyscrapers (hard version) 单调栈

原文:https://www.cnblogs.com/cminus/p/12373088.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!