AGC029C - Lexicographic constraints

記錄我心路歷程吧,這道小水題暴露出我不少問題。ios


給定 $n$ 個字符串長度 $a_i$ ,求字符集最小多大,才能構造出按字典序比較 $s_1 < s_2 < \dots < s_n$。c++

當 $a_i < a_{i+1}$ 時,顯然全補 $0$ 就行。不然,是一個高精度 $+1$。二分字符集大小,判斷行不行。code


如下是我作題過程。blog

首先,除了二分部分,所有推出來了。可是加法的細節寫爛了,各類沒判。ci

而後沒有特判字符集爲 $1$ 的狀況,硬是跑了 1e9 差點T。(最後改改仍是T了)字符串

而後考慮貪心的過程,寫了一個錯的。在字符不夠的時候新開一個,實際上會致使前面的浪費。it

blog 寫到最後發現仍是一道sb題,就當水了一個 blog 吧。io

#include <bits/stdc++.h>
const int MAXN = 500010;

int n, st[MAXN], col[MAXN], top;
void add() {
	if (st[top] > 1 && st[top - 1] != st[top] - 1) {
		st[top + 1] = st[top];
		col[top + 1] = col[top];
		--st[top]; ++top;
	}
	++col[top];
}
int A[MAXN];
bool judge(int cnt) {
	int lst = 0;
	memset(st, 0, top + 1 << 2);
	memset(col, 0, top + 1 << 2);
	top = 0;
	for (int i = 1, t; i <= n; ++i) {
		t = A[i];
		if (lst < t) {
			if (!top || col[top] != 0) st[++top] = t, col[top] = 0;
			else st[top] = t;
		} else {
			int k = -1;
			while (st[top] > t) k = col[top], --top;
			if (st[top] != t) st[++top] = t, col[top] = k;
			if (cnt > 1) {
				add();
				while (top && col[top] >= cnt) {
					int at = st[top]; --top;
					if (st[top] + 1 != at)
						st[++top] = at - 1;
					add();
				}
			} else top = 0, col[0] = 1;
			if (col[0]) return false;
			if (st[top] != t) st[++top] = t, col[top] = 0;
		}
		lst = t;
	}
	return true;
}
int main() {
	std::ios_base::sync_with_stdio(false), std::cin.tie(0);
	std::cin >> n;
	for (int i = 1; i <= n; ++i) std::cin >> A[i];
	int l = 1, r = n, ans = 0;
	while (l <= r) {
		int mid = l + r >> 1;
		if (judge(mid)) ans = mid, r = mid - 1;
		else l = mid + 1;
	}
	std::cout << ans << std::endl;
	return 0;
}
相關文章
相關標籤/搜索