zoukankan      html  css  js  c++  java
  • [CF594E]Cutting the Line

    $ ewcommand{qed}{square}$字符串神题。

    要点:Lyndon分解,扩展KMP, 最小循环表示,贪心。

    题目链接

    题意

    已知字符串 $S$, 请你把它切成不超过 $k$ 段,并翻转其中若干段,使得最终字符串的字典序最小。

    题解

    先想一想如果 $k=|S|$, 即不限制切的段数怎么做。此时我们发现可以去掉“是否翻转”的决策,因为如果有一段不翻转,我们就把它拆成若干个单字符分别翻转。

    我们的策略是:

    策略1. 设反串 $S^r$ 的Lyndon分解为 $s_1, s_2, ldots, s_n, t_1, t_2, ldots, t_m$, 其中 $s_n e t_1=t_2=cdots=t_m$. 每次取出 $t_1 t_2 cdots t_m$ 对应的原串前缀 $S[:L]$ 作为第一段,余下的化归为关于 $S[L:], k-1$ 的问题。

    证明 简化问题的操作等价于每次剪切出一个反串的后缀,按剪切的顺序先后从左到右连接。因此我们应该使最小后缀,即 $t_1$ 在开头出现尽可能多次。$S^r$ 可以写成 $A_1(c_1 imes t_1)A_2(c_2 imes t_1) cdots A_t(c_t imes t_1)$ 的形式,$c_t=m$. 那么最优情况下应该使 $c_t+max{c_1+c_2+cdots+c_{t-1}}$ 个 $t_1$ 作为先导。为取到该最大值,最优策略应该先切出最后的 $m$ 个 $t_1$.

    $qed$

    于是简化的问题得到解决。想一想原问题,我们仍然假设每一段都必须翻转,并加入修正规则:如果连续若干个段都是单字符,它们实际上只占据一段。

    当 $kge3$ 时,策略1改进后也成立:

    策略1-改. 设反串 $S^r$ 的Lyndon分解为 $s_1, s_2, ldots, s_n, t_1, t_2, ldots, t_m$, 其中 $s_n e t_1=t_2=cdots=t_m$ 或者 $|s_n|>|t_1|=|t_2|=cdots=|t_m|=1$. 每次取出 $t_1 t_2 cdots t_m$ 对应的原串前缀 $S[:L]$ 作为第一段,余下的化归为关于 $S[L:], k-1$ 的问题。

    证明 如果 $|t_1| ge 2$, 由于 $k ge 3$, 策略1的证明仍然有效。如果 $|t_1|=1$, 那么为了节省段数一定一并取出这些单字符。

    $qed$

    先对 $k ge 3$ 的情况反复应用策略1-改,所以现可不妨假设 $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$ 为本情况的最优解之一。

    证明 若 $L$ 不是Lyndon分解中两相邻字符串的分界点,那么取它之后的一个分界点作为 $L$ 更优;若 $L$ 是两相等字符串的分界点,分类讨论可发现此相等段的两端点中至少有一个是不会更劣的决策。

    $qed$

    性质2. 如果设 $p$ 为最大的小于 $n$ 的正整数,满足 $S^r[d_p:]$ 不为 $S^r[d_{p+1}:]$ 的前缀,特别地,若不存在如此的正整数则设 $p=0$, 则 $q>p$.

    证明 此命题等价于 $forall q<i le n$, $S^r[d_i:]$ 为 $S^r[d_q:]$ 的前缀。否则取 $d_i$ 更优。

    $qed$

    性质3. $forall p<i<n,$ $d_{i+1}-d_i>|S|-d_{i+1}$. 这表明枚举查找 $p$ 的时间为 $O(|S|)$.

    证明 假设性质不成立,得 $S[d_i:]$ 有长度为 $d_{i+1}-d_i>{1over2}(|S|-d_i)$ 的周期,矛盾。

    $qed$

    性质4. 当 $p<m le n$ 时,设 $T_m=S^r[d_m:]S[-d_m:]$, 若 $T_{m-1}>T_m$, 则 $forall p<i<m, T_i>T_m$.

    证明 $ecause T_{m-1}>T_m$, $T_m[-d_{m-1}:]=T_{m-1}[-d_{m-1}:]$

    $ herefore T_m[:-d_{m-1}]<T_{m-1}[:-d_{m-1}]=S^r[d_{m-1}:]=T_i[:-d_{m-1}]$

    $ herefore T_m<T_i$.

    $qed$

    因此只需要枚举找到最大的整数 $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|)$ 时空内解决。

    不知道有没有漏洞的实现链接

  • 相关阅读:
    GIT
    JS常用功能
    prop checkbox 是否选中的问题。
    关于 未能加载文件或程序集“MySql.Web.v20 ...... 的问题
    Codeforces Round #535(div 3) 简要题解
    [Codeforces 600E] Lomsat gelral
    [PA 2011] Journeys
    [HNOI 2012] 永无乡
    [ONTAK2010] Peaks
    [BZOJ 3307] 雨天的尾巴
  • 原文地址:https://www.cnblogs.com/nealchen/p/CF594E.html
Copyright © 2011-2022 走看看