• C2. Skyscrapers (hard version)


    思路:

    显然满足题意的一定是一个单峰序列,于是可以考虑第i个当最高点的时候,左边的最大总和,而这个是可以递推的,因为当m[i]>=m[i-1]的时候第i个可以直接取m[i]加上去,而当m[i] < m[i-1]的时候,要把之前所有大于m[i]的都变成m[i],而之前的部分是单增的,于是可以开个单调栈来维护,复杂度O(n),同理右边的最大总和也可以这么算。

    #include <iostream>
    #include <algorithm>
    #include <string>
    #include <string.h>
    #include <vector>
    #include <map>
    #include <stack>
    #include <set>
    #include <queue>
    #include <math.h>
    #include <cstdio>
    #include <iomanip>
    #include <time.h>
    #include <bitset>
    #include <cmath>
    #include <sstream>
    
    #define LL long long
    #define INF 0x3f3f3f3f
    #define ls nod<<1
    #define rs (nod<<1)+1
    
    const double eps = 1e-10;
    const int maxn = 5e5 + 10;;
    const LL mod = 1e9 + 7;
    
    int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
    using namespace std;
    
    struct node {
        int val,cnt;
    }nd[maxn];
    
    int a[maxn],b[maxn];
    LL f[maxn],g[maxn];
    int main() {
        int n;
        cin >> n;
        for (int i = 1;i <= n;i++)
            cin >> a[i];
        int cnt = 0;
        for (int i = 1;i <= n;i++) {
            if (a[i] >= a[i-1]) {
                nd[++cnt].val = a[i];
                nd[cnt].cnt = 1;
                f[i] = f[i-1] + a[i];
            }
            else {
                LL sum = 0;
                int num = 0;
                while (cnt >= 1 && nd[cnt].val >= a[i]) {
                    sum += nd[cnt].val * 1ll * nd[cnt].cnt;
                    num += nd[cnt].cnt;
                    cnt--;
                }
                nd[++cnt].val = a[i];
                nd[cnt].cnt = num+1;
                f[i] = f[i-1] - sum + 1ll*nd[cnt].val*nd[cnt].cnt;
            }
        }
        cnt = 0;
        for (int i = n;i >= 1;i--) {
            if (a[i] >= a[i+1]) {
                nd[++cnt].val = a[i];
                nd[cnt].cnt = 1;
                g[i] = g[i+1] + a[i];
            }
            else {
                LL sum = 0;
                int num = 0;
                while (cnt >= 1 && nd[cnt].val >= a[i]) {
                    sum += nd[cnt].val * 1ll * nd[cnt].cnt;
                    num += nd[cnt].cnt;
                    cnt--;
                }
                nd[++cnt].val = a[i];
                nd[cnt].cnt = num+1;
                g[i] = g[i+1] - sum + 1ll*nd[cnt].val*nd[cnt].cnt;
            }
        }
        int id = 1;
        for (int i = 2;i <= n;i++) {
            if (f[i] + g[i] - a[i] > f[id] + g[id] - a[id]) {
                id = i;
            }
        }
        b[id] = a[id];
        for (int i = id-1;i >= 1;i--) {
            b[i] = min(b[i+1],a[i]);
        }
        for (int i = id+1;i <= n;i++) {
            b[i] = min(b[i-1],a[i]);
        }
        for (int i = 1;i <= n;i++) {
            cout << b[i] << " ";
        }
        cout << endl;
        return 0;
    }
  • 相关阅读:
    jQuery Mobile-jquery Mobile 怎么用ajax提交表单
    Passing data between pages in JQuery Mobile | Ram's Blog
    jQuery Mobile Docs
    jquery mobile header title左对齐 button右对齐
    jquery mobile -role
    jQueryMobile$(document).ready 等价于?( jQuery mobi...
    HTML5,jQuery Mobile 可视化生成器 Tiggzi
    WebApi系列~开放的CORS,跨域资源访问对所有人开放
    WebApi系列~目录
    WebApi系列~基于单请求封装多请求的设计~请求的安全性设计与实现
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/12392361.html
Copyright © 2020-2023  润新知