标签:部分 i+1 min 连续 比较大小 之一 算法 strong 大小
字符串神题。
要点:Lyndon分解,扩展KMP, 最小循环表示,贪心。
已知字符串 $S$, 请你把它切成不超过 $k$ 段,并翻转其中若干段,使得最终字符串的字典序最小。
题解
先想一想如果 $k=|S|$ 怎么做。此时我们发现可以去掉“是否翻转”的决策,因为如果有一段不翻转,我们就把它拆成若干个单字符分别翻转。
我们的策略是:
策略1. 每次切出反串字典序最小的后缀对应的原串前缀翻转,然后去掉这个前缀接着做。
证明:如果2019年内没补上就是鸽了。
在这种情况下,我们可以对反串 $S^r$ 作Lyndon分解,不难发现Lyndon分解实际上就是这个过程。
然后想一想原问题,我们发现两个事实:
这样可以尽量地节省步数。当 $k\ge3$ 时,策略1改进后也成立:
策略1改. 每次切出反串Lyndon分解中的最后极长的「相等段」或者「单字符段」对应的原串前缀翻转,然后去掉这个前缀接着做。
证明:如果2019年内没补上就是鸽了。
于是,现不妨假设 $k \le 2$.
如果 $S^r$ 已经是 Lyndon 串,那么显然答案就是 $S^r$; 如果 $k=1$, 那么显然答案就是 $\min\{S, S^r\}$.
现在,字符串将被我们分为前后两部分,并按照这两部分是否翻转分为三大类操作,或者不操作直接留下 $S$.
(一)前一部分翻转,后一部分不翻转,设为 $S^r[L:]S[-L:]$.
设 $S^r$ 的Lyndon分解合并相等段后为 $S^r[:d_1], S^r[d_1:d_2], \ldots, S^r[d_{n-1}:d_n]$, 其中 $d_n=|S|$, 那么我们有结论:
性质1. 存在整数 $q \in [1, n]$ 使得 $L=d_q$ 为本情况的最优解之一。
性质2. 如果设 $p$ 为最大的小于 $n$ 的正整数,满足 $S^r[d_p:]$ 不为 $S^r[d_{p+1}:]$ 的前缀,特别地,若不存在如此的正整数则设 $p=0$, 则 $q>p$.
性质3. $\forall p<i<n,$ $d_{i+1}-d_i \le |S|-d_i$. 这表明枚举查找 $p$ 的时间为 $O(|S|)$.
性质4. 当 $p<m \le n$ 时,S^r[d_m:]S[-d_m:]$ 是单峰函数。
以上四条性质的证明:如果2019年内没补上就是鸽了。
因此只需要枚举找到最大的整数 $q$ 使得 $q=p+1$ 或 $S^r[d_q:]S[-d_q:]<S^r[d_{q-1}:]S[-d_{q-1}:]$, 后者等价于 $S[-d_{q-1}:-d_q]<S^r[d_{q-1}-d_q+|S|:]$, 因此直接比较的总时间也是 $O(|S|)$.
(二)前一部分不翻转,后一部分翻转,设为 $S[:L]S^r[:-L]$.
设 $i<j$, 比较 $S[:i]S^r[:-i]$ 与 $S[:j]S^r[:-j]$ 实际上相当于比较 $S^r[:-i]=S^r[:j-i]S^r[j-i:-i]$ 与 $S^r[i:j]S^r[:-j]$, 于是可以考虑用扩展 $KMP$ 算法求这两个串的最长公共前缀以比较大小。
(三)两部分都翻转,即 $S^r$ 的循环表示。求最小循环表示即可。
综上所述,本题可以在 $O(|S|)$ 时空内解决。
标签:部分 i+1 min 连续 比较大小 之一 算法 strong 大小
原文地址:https://www.cnblogs.com/nealchen/p/12002676.html