zoukankan      html  css  js  c++  java
  • Codeforces Skyscrapers (hard version)

    Skyscrapers (hard version)

    题目链接:https://codeforces.com/contest/1313/problem/C2

    解题思路:我们最后建好的高楼一定是一个倒v的形状,因此我们可以考虑用一个数组s[i]表示最高点位于位置i的时候能够得到的最大值,则在i点的两个一定是单调递减的(也可以看作单调递增的,从两边往中间看的话)则我们用一个单调栈来维护这个序列 从两边往中间楼高一定是递增的,因此维护一个单调递减栈,当我们新加入一个楼时,如果比栈顶元素的高度要高,则高度和就可以加上新楼的高度,但是如果比当前的小的话,就要进行出栈处理并且减掉这些出栈的楼的影响,最后再加上新楼的高度*删去的楼的数目就行(相当于把之前不符合的全部减小了一下),最后统计答案即可

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=5e5+10;
    typedef unsigned long long ll;
    stack<int>q;
    ll a[maxn],s[maxn],n;
    void getans(int flag)
    {
        /* 1和0分别表示从左向右和从右向左,因此会有不同的处理方式,同时再从右向左的时候,最高点会被枚举两次,因此需减少一下*/ 
        ll sum=0;
        q.push(0);
        for(int i=1;i<=n;i++)
        {
            while(!q.empty()&&a[i]<a[q.top()])
            {
                int now=q.top();
                q.pop();
                sum-=1ll*(now-q.top())*a[now];
            }
            sum+=1ll*(i-q.top())*a[i];
            if(flag)
            s[i]+=sum;
            else s[n-i+1]+=sum-a[i];
            q.push(i);
        }
        while(!q.empty()) q.pop();
    }
    int main()
    {
        /*Codeforces  1313*/
        cin>>n;
        for(int i=1;i<=n;i++) cin>>a[i];
        getans(1);
        reverse(a+1,a+1+n);
        getans(0);
        reverse(a+1,a+1+n);
        int pos=max_element(s+1,s+1+n)-s;
    //    for(int i=1;i<=n;i++) cout<<s[i]<<" ";
        for(int i=pos-1;i;i--) if(a[i]>a[i+1]) a[i]=a[i+1];
        for(int i=pos+1;i<=n;i++) if(a[i]>a[i-1]) a[i]=a[i-1];
        for(int i=1;i<=n;i++) cout<<a[i]<<" ";
        cout<<endl;
        return 0;
    }
    //-8 4 -2 -6 4 7 1
    //1  0  0  0 1 1 0
  • 相关阅读:
    springmvc两种非注解的处理器适配器
    springmvc两种非注解的处理器映射器
    java线程数据交换Exchanger
    java计数器CountDownLatch
    java路障CyclicBarrier
    java线程condition
    java模拟数据库缓存
    java中的递归
    面向对象
    全概率公式和贝叶斯准则
  • 原文地址:https://www.cnblogs.com/tombraider-shadow/p/13687293.html
Copyright © 2011-2022 走看看