zoukankan      html  css  js  c++  java
  • AGC029C

    看来细节比较多...

    显然需要二分.
    考虑用贪心来判断当前的 (mid) 是否可行, 从 (1) 枚举到 (n):

    • 如果 (a_i > a_{i-1}), 那么直接在后面添 (0) 即可.
    • 如果 (a_i leq a_{i-1}), 那么贪心, 在 (a_{i-1}) 的基础上找到第一个 (leq a_i) 且值不为 (mid) 的位置, 然后将它的值 (+1).

    如果某次找不到这样的位置了则说明 (mid) 不行.
    考虑到直接维护是 O(值域) 的, 可能接受不了, 但每次修改都是连续的一段.
    所以这个东西可以用栈来维护, 那么复杂度就正确了.

    贴上代码:

    #include <bits/stdc++.h>
    #define N 200200
    #define fi first
    #define se second
    #define pii pair<int, int>
    using namespace std;
    
    int n, a[N], top;
    pii stk[N];
    
    inline bool check(int mid) {
        stk[0] = make_pair(0, 0);
        stk[top = 1] = make_pair(1, a[1]);
        for (int i = 2; i <= n; ++i) {
            if (a[i] > a[i - 1]) {
                while (top && stk[top].fi == 1) 
                    --top;
                stk[++top] = make_pair(1, a[i]);
            } else {
                int now = 0;
                while (top && stk[top].se >= a[i])
                    now = stk[top--].fi;
                if (now < mid) {
                    if (stk[top].se != a[i] - 1)
                        stk[++top] = make_pair(now, a[i] - 1);
                    else while (top && stk[top].fi == now + 1) --top;
                    stk[++top] = make_pair(now + 1, a[i]);
                } else {
                    if (!top) return false;
                    now = stk[top].fi;
                    int pos = stk[top].se;
                    if (stk[top - 1].se == pos - 1) {
                        if (top) for (--top; top && stk[top].fi == now + 1; --top);
                        stk[++top] = make_pair(now + 1, pos);
                    } else stk[top].se--, stk[++top] = make_pair(now + 1, pos);
                    stk[++top] = make_pair(1, a[i]);
                }
            }
        }
        return true;
    }
    
    int main() {
    
        cin >> n;
        bool chk = 1;
        for (int i = 1; i <= n; ++i) {
            scanf("%d", a + i);
            if (a[i] <= a[i - 1]) chk = false;
        }
        if (chk) return puts("1"), 0;
    
        int l = 2, r = n - 1, res = n;
        while (l <= r) {
            int mid = (l + r) >> 1;
            if (check(mid)) r = (res = mid) - 1;
            else l = mid + 1;
        }
    
        cout << res << endl;
    
        return 0;
    }
    
  • 相关阅读:
    Javascript FP-ramdajs
    微信小程序开发
    SPA for HTML5
    One Liners to Impress Your Friends
    Sass (Syntactically Awesome StyleSheets)
    iOS App Icon Template 5.0
    React Native Life Cycle and Communication
    Meteor framework
    RESTful Mongodb
    Server-sent Events
  • 原文地址:https://www.cnblogs.com/hnfms-jerry/p/solution_agc029c.html
Copyright © 2011-2022 走看看