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

    题目链接


    题解思路:

    利用单调栈去找出每一个位置 i 左边第一个高度小于它的位置 L 和右边第一个高度小于它的位置 R ,然后在区间 (L,i] 所能取到的最大值即为h[ i ],这段区间对整体的贡献就是 (i - L) * h[ i ],对右边做同样处理,最后我们只需要找到它整体最大的那个位置即可。


    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> PII;
    #define ls l,mid,rt<<1
    #define rs mid+1,r,rt<<1|1
    #define endl '
    '
    const int MAXN = 1e6+10;
    const double EPS = 1e-12;
    const ll mod = 1e9+7;
    
    int n;
    ll a[MAXN],l[MAXN],r[MAXN];
    stack<int>st;
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
        for(int i=1;i<=n;i++){
            while(!st.empty()&&a[st.top()]>=a[i])st.pop();
            if(st.empty())l[i]=a[i]*i;
            else l[i]=l[st.top()]+a[i]*(i-st.top());
            st.push(i);
        }
        while(!st.empty())st.pop();
        for(int i=n;i>=1;i--){
            while(!st.empty()&&a[st.top()]>=a[i])st.pop();
            if(st.empty())r[i]=a[i]*(n-i+1);
            else r[i]=r[st.top()]+a[i]*(st.top()-i);
            st.push(i);
        }
        ll maxx=0,id=0;
        for(int i=1;i<=n;i++){
            if(l[i]+r[i]-a[i]>maxx){
                maxx=l[i]+r[i]-a[i];
                id=i;
            }
        }
        for(int i=id-1;i>=1;i--)a[i]=min(a[i],a[i+1]);
        for(int i=id+1;i<=n;i++)a[i]=min(a[i],a[i-1]);
        for(int i=1;i<=n;i++)cout<<a[i]<<" ";
    }
  • 相关阅读:
    扩展欧几里得算法
    poj-3094-quicksum
    (floyd)佛洛伊德算法
    poj-3660-cows contest(不懂待定)
    poj-1056-IMMEDIATE DECODABILITY(字典)
    delete与delete[]的区别
    poj-1046-color me less
    SqlParameter 使用
    VS2010中出现无法嵌入互操作类型(转)
    fastreport代码转
  • 原文地址:https://www.cnblogs.com/Mmasker/p/12374087.html
Copyright © 2011-2022 走看看