AGC029C - Lexicographic constraints 题解

Posted hnfms-jerry

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AGC029C - Lexicographic constraints 题解相关的知识,希望对你有一定的参考价值。

当时考试的时候就遇到了这道题...然而并没有写出来.
现在看来感觉细节的确比较多...

显然需要二分.
考虑用贪心来判断当前的 (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 <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <map>
#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;
}

以上是关于AGC029C - Lexicographic constraints 题解的主要内容,如果未能解决你的问题,请参考以下文章

URAL1081 Binary Lexicographic Sequence(递归)

Binary Lexicographic Sequence URAL - 1081 (有关数的排列)

agc045_c Range Set

AGC 043 C,D 题解

AtCoder AGC038 C-LCMs 题解

agc032_c