• 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;
    }
    
  • 相关阅读:
    docker一些基本操作
    Error requesting socket: exit status 255(一个很不错的解决办法)【转】
    十五周至十八周的任务进度
    7月24号day16总结
    7月23号day15总结
    7月22号day14总结
    7月21号day13总结
    7月20号day12总结
    7月19日day11总结
    7月18号day10总结
  • 原文地址:https://www.cnblogs.com/hnfms-jerry/p/solution_agc029c.html
Copyright © 2020-2023  润新知