加载中...

cf div2 1087 E(KMP好题)

E. A Trivial String Problem

一个字符串 \(s\) 的 border:既不空也不是该字符串本身,且同时为 \(s\) 的前缀与后缀。

对于 KMP,求解出的 \(next_{i}\)\(s_{1\backsim i}\) 的最长 border 长度,可以 \(O(n)\) 线性得到。那么如何线性求出 \(s\) 的最短 border 长度呢(设为 \(b_{i}\))?事实上,\(b_{i}\) 可以利用 \(next_{i}\) 得到。

结论:

pe1mG0H.png

证明:

  1. 不存在最长 border,自然也不存在最短 border。(1)证毕。
  2. 对于整个字符串的最短 border,一定完全包含在最长 border 内。因此计算 \(b_{i}\) 等价于计算 \(b_{next_{i}}\)
  3. \(s_{next_{i}}\) 不存在 border,即 \(next_{next_{i}} = 0\),则 \(s_{i}\) 的最长 border 与最短 border 相等,\(b_{i} = next_{i}\);否则 \(s_{next_{i}}\) 存在 border,那么 \(s_{i}\) 的最短 border 与 \(s_{next_{i}}\) 的最短 border 相等,\(b_{i} = b_{next_{i}}\)。(2、3 证毕)

对于本题,需要利用字符串的最短 border。

结论:在整个字符串的最优划分中,每一部分子串一定不存在 border。这很好证明,若某一部分存在 border,则显然该部分还能继续划分,使得划分个数更多,答案更优。

考虑该字符串划分中的最后一部分,显然它要么是字符串本身(即只有一个部分),要么是该字符串的最短 border(否则还能继续划分;由划分规则可知每个部分必须是原串的 border)。故我们会发现对于任何字符串,其最优划分的最后一部分是固定且唯一的。

那么剩下的部分就是一个子问题,可以按照上述思路递归展开。

因此对于一个字符串的最优划分,一定是不断地从后缀中取出最短 border,直到剩余部分不存在 border。显然直接利用 \(b_{i}\) 递推即可。

code

posted @ 2026-03-28 17:58  小橘奏  阅读(18)  评论(0)    收藏  举报