寒假刷题38: Codeforces Round #622 (Div. 2) C2. Skyscrapers (hard version)

题目链接:

Codeforces Round #622 (Div. 2) C2. Skyscrapers (hard version)

题目解析:

在C1中,我们让每一个点作为顶点,然后遍历数组,这在C2中显然会超时,现在考虑如何优化.

在遍历的过程中,如果一个点可建造的高度h[i]大于等于当前可建造的最大高度maxhigh,显然不用更新maxhigh.只有当h[i]<maxhigh,才会把maxhigh更新为a[i].也就是说,我们无需遍历每一个点,只需要快速找到一个点左右两边第一个小于它的数.这显然是单调栈问题

(真没想到之前刚刷了几道单调栈的题就派上用场了^_^)

AC代码:

#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
typedef long long ll;
const int MAXX = 500005;
ll h[MAXX],n;
ll ls[MAXX],rs[MAXX],sum[MAXX];
ll l[MAXX],r[MAXX];
ll ans[MAXX];
stack<int> s;
int main()
{
    cin >> n;
    for (int i=1; i<=n; i++)
    {
        cin >> h[i];
        sum[i] = sum[i-1] + h[i];
    }
    for (int i=1;i<=n; i++)
    {
        while(!s.empty() && h[s.top()] >= h[i]) s.pop();
        if (s.empty()) l[i] = 0;
        else l[i] = s.top();
        s.push(i);
    }
    while(!s.empty()) s.pop();
    for (int i=n; i; i--)
    {
        while(!s.empty() && h[s.top()] >= h[i]) s.pop();
        if (s.empty()) r[i] = n+1;
        else r[i] = s.top();
        s.push(i);
    }
    for (int i=1; i<=n; i++)
        ls[i] = ls[l[i]] + (i-l[i])*h[i];
    for (int i=n; ~i; i--)
        rs[i] = rs[r[i]] + (r[i]-i)*h[i];
    ll maxi = 0, maxv = -1;
    for (int i=1; i<=n; i++)
        if (ls[i]+rs[i]-h[i] > maxv)
            maxi = i, maxv = ls[i]+rs[i]-h[i];

    for (int i=maxi; i; i=l[i])
        for (int j=i; j>l[i]; j--) ans[j] = h[i];
    for (int i=maxi; i; i=r[i])
        for (int j=i; j<r[i]; ++j)
            ans[j] = h[i];
    for (int i=1; i<=n; i++)
        cout << ans[i] << ' ';
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值