CF1313C2 Skyscrapers (hard version) 题解 单调队列

题目链接:

解题思路:单调队列。

题解以后补上。

实现代码如下:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 500050;
int n;
long long h[maxn], tmp, f1[maxn], f2[maxn], ans, num[maxn];
deque<long long> que;
int main() {
    cin >> n;
    for (int i = 1; i <= n; i ++) cin >> h[i];
    for (int i = 1; i <= n; i ++) {
        num[i] = 1;
        while (!que.empty() && h[que.back()] > h[i]) {
            int j = que.back();
            tmp -= h[j]*num[j];
            num[i] += num[j];
            que.pop_back();
        }
        que.push_back(i);
        tmp += num[i]*h[i];
        f1[i] = tmp;
    }
    tmp = 0;
    que.clear();
    for (int i = n; i >= 1; i --) {
        num[i] = 1;
        while (!que.empty() && h[que.back()] > h[i]) {
            int j = que.back();
            tmp -= h[j]*num[j];
            num[i] += num[j];
            que.pop_back();
        }
        que.push_back(i);
        tmp += num[i]*h[i];
        f2[i] = tmp;
    }
    int j = 1;
    for (int i = 0; i <= n; i ++) {
        if (ans < f1[i] + f2[i] - h[i]) {
            j = i;
            ans = f1[i] + f2[i] - h[i];
        }
    }
    for (int i = j-1; i >= 1; i --) h[i] = min(h[i], h[i+1]);
    for (int i = j+1; i <= n; i ++) h[i] = min(h[i], h[i-1]);
    for (int i = 1; i <= n; i ++) cout << h[i] << " ";
    return 0;
}
posted @ 2020-04-08 20:25  quanjun  阅读(242)  评论(0)    收藏  举报