zoukankan      html  css  js  c++  java
  • Codeforces Round #622 (Div. 2) C2. Skyscrapers (hard version) 单调栈

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

    问题

    传送门

    我是参考了这篇题解传送门,然后按着思路做出了的(但大佬题解中的sumr[]数组操作我没看懂,然后自己改了改)。

    摘抄:

    维护峰值最优
    找左右边的第一个比自己小的元素,维护前缀和,找最大的峰值
    l[i]:用单调栈维护左边第一个比它小的数
    r[i]:用单调栈维护右边第一个比它小的数
    suml[i]:左边的前缀和
    sumr[i]:右边的前缀和
    然后遍历一遍数组,找到最大的峰值在哪

    代码

    #include <cstdio>
    #include <iostream>
    #include <queue>
    #include <cmath>
    #include <algorithm>
    #include <cstring>
    #include <set>
    #include <stack>
    using namespace std;
    #define ll long long
    #define P pair<int,int>
    const int N=5e5+10;
    const ll INF =  ~(1LL<<63);
    ll a[N],b[N],l[N],r[N],suml[N],sumr[N];
    int n;
    stack<ll>st;
    int main()
    {
        ios::sync_with_stdio(false);
        cin >> n;
        for(int i=1;i<=n;i++)
            cin >> a[i];
        for(int i=1;i<=n;i++)
        {
            while(st.size()&&a[st.top()]>=a[i])
                st.pop();
            if(st.empty())
                l[i] = 0;
            else
                l[i] = st.top();
            st.push(i);
        }
        while(st.size())
            st.pop();
        for(int i=n;i>=1;i--)
        {
            while(st.size()&&a[st.top()]>=a[i])
                st.pop();
            if(st.empty())
                r[i] = n+1;
            else
                r[i] = st.top();
            st.push(i);
        }
        for(int i=1;i<=n;i++)
            suml[i] = suml[l[i]] + (i-l[i])*a[i];
        for(int i=n;i>=1;i--)
            sumr[i] = sumr[r[i]] + (r[i]-i)*a[i];
        ll maxn = 0,pos;
        for(int i=1;i<=n;i++)
        {
            ll cnt =  suml[i] + sumr[i] - a[i];
            if(maxn < cnt)
            {
                maxn = cnt;
                pos = i;
            }
        }
        b[pos] = a[pos];
        for(int i=pos-1;i>=1;i--)
        {
            b[i] = min(b[i+1],a[i]);
        }
        for(int i=pos+1;i<=n;i++)
        {
            b[i] = min(a[i],b[i-1]);
        }
        for(int i=1;i<=n;i++)
        {
            cout << b[i] << " ";
        }
        return 0;
    }
    
  • 相关阅读:
    第一阶段-意见评论
    团队冲刺第15天
    团队冲刺第14天
    第十三周进度报告
    团队冲刺第13天
    团队冲刺第12天
    团队冲刺第11天
    SCRUM第二阶段第九天
    SCRUM第二阶段第八天
    SCRUM第二阶段第七天
  • 原文地址:https://www.cnblogs.com/hh13579/p/12384835.html
Copyright © 2011-2022 走看看