「简单题」 [Codeforces 1209C] Paint the Digits

皎月半洒花

2020-06-16 21:28:39

Solution

一开始猜了一个把 LIS 找出来就完了。然后发现假的离谱。然后就考虑观察性质,发现如果存在合法答案,那么对于一个 $i$ 如果位置不变,会有 $1\sim i-1$ 都 $\leqslant i$ 。不难发现这是个十分强的必要条件。于是可以这么把答案取出来,然后去 check 一下充分性就好了。复杂度线性。 ```cpp #include <cstdio> #include <vector> #include <cstring> #include <algorithm> const int N = 301000 ; using namespace std ; int n, T ; int maxc ; int maxv ; int res[N] ; int ans[N] ; int base[N] ; bool vis[N] ; vector <int> ans1, ans2 ; int main(){ scanf("%d", &T) ; while (T --){ scanf("%d", &n) ; maxv = maxc = 0 ; ans2.clear() ; ans1.clear() ; memset(vis, 0, sizeof(vis)) ; for (int i = 1 ; i <= n ; ++ i) scanf("%1d", &base[i]) ; for (int i = 1 ; i <= n ; ++ i) if (maxv > base[i]) vis[i] = 1, maxc = max(base[i], maxc) ; else maxv = std :: max(maxv, base[i]) ; for (int i = 1 ; i <= n ; ++ i){ if (vis[i] || base[i] < maxc) ans1.push_back(i) ; else ans2.push_back(i) ; } int cnt = 0 ; for (auto k : ans1) ans[k] = 1, res[++ cnt] = base[k] ; for (auto k : ans2) ans[k] = 2, res[++ cnt] = base[k] ; // for (int i = 1 ; i <= n ; ++ i) printf("%d ", res[i]) ; puts("") ; for (int i = 1 ; i <= n ; ++ i) if (res[i] < res[i - 1]) goto cc ; for (int i = 1 ; i <= n ; ++ i) printf("%d", ans[i]) ; puts("") ; continue ; cc : puts("-") ; } } ``` #