Skyscrapers

Posted cadcadcad

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Skyscrapers相关的知识,希望对你有一定的参考价值。

C2 - Skyscrapers (hard version)

分别用s1[i],s2[i]表示在 i 位置能取到的左边的值之和,右边的值之和。

利用单调栈的思想。

降低复杂度的方法是,充分利用重复计算的数据,将其保存下来,避免多次计算。

// Created by CAD on 2020/2/24.
#include <bits/stdc++.h>

#define fi first
#define se second
#define pli pair<long long,int>
#define ll long long
using namespace std;

const int maxn=5e5+5;
int m[maxn];
ll s1[maxn],s2[maxn];
stack<pli> s;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;cin>>n;
    for(int i=1;i<=n;++i)
        cin>>m[i];
    s.push({0,0});
    for(int i=1;i<=n;++i){
        while(s.top().fi>m[i]) s.pop();
        s1[i]=1ll*(i-s.top().se)*m[i]+s1[s.top().se];
        s.push({m[i], i});
    }
    while(s.size()) s.pop();
    s.push({0,0});
    for(int i=1;i<=n;++i){
        while(s.top().fi>m[n-i+1]) s.pop();
        s2[n-i+1]=1ll*(i-s.top().se)*m[n-i+1]+s2[n-s.top().se+1];
        s.push({m[n-i+1], i});
    }
    ll msum=0,bj=0;
    for(int i=1;i<=n;++i)
        if(msum<s1[i]+s2[i]-m[i]) msum=s1[i]+s2[i]-m[i],bj=i;
    int maxx=m[bj];
    for(int i=bj-1;i>=1;--i)
        m[i]=min(maxx,m[i]),maxx=m[i];
    maxx=m[bj];
    for(int i=bj+1;i<=n;++i)
        m[i]=min(maxx,m[i]),maxx=m[i];
    for(int i=1;i<=n;++i)
        cout<<m[i]<<" 
"[i==n];
    return 0;
}

以上是关于Skyscrapers的主要内容,如果未能解决你的问题,请参考以下文章

Skyscrapers Aren’t Scalable

cf1313c-Skyscrapers-单调栈

「CF1313C Skyscrapers」

CF335 ECounting Skyscrapers

C.Skyscrapers

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