POI2011 Periodicity
Updated On 2022.02.01:情况 4 细节添加,也算是解决了第一次做这个题的时候一些口胡上的疑惑
2011年就能出出这样充满科技感+脑力的题,佩服POI Orz
约定:字符串 的下标从 开始, 表示 的第 到第 个字符构成的子串。
串 有长度为 的周期等价于其有长度为 的 border。
设函数 表示字典序最小的、border 集合与 的 border 集合相同的 字符串。分为以下情况:
- 如果 中所有字符相同,返回 个 构成的字符串;
- 如果 周期集合为空,返回 个 接上 个 构成的字符串;
- 如果 最短的周期长度 满足 ,设 ,则 可表示为 的形式,其中 是 的一个前缀,可为空。
- 如果 最短的周期长度 满足 ,设 border 为 ,那么 就可以表示为 的形式,其中 是一个任意字符串,不能为空。
1 和 2 情况的构造是显然的。
对于 3 情况,递归进入 求解。设 ,那么就把 重复若干次拼上 ,即可得到答案。
在证明正确性前先来复习有关周期和 border 的几个 OI 界众所周知的简单定理。
- Weak Periodicity Lemma:对于一个字符串 ,若其有长度为 和长度为 的周期,且 ,则 有长度为 的周期。
Proof. 设 ,令 。因为 ,所以 和 至少有一个成立,故可以先向后跳 再向前跳 ,或者先向前跳 再向后跳 ,可得 。那么 也是 的周期。根据辗转相除法, 也是 的一个周期。QED
- 一个推论:设 最短周期长度为 ,且 ,则 的 border 集合中 的元素一定构成集合 。
Proof. 首先这些元素一定会包含在 border 集合内。考虑使用反证法证明不存在其他的元素。
设有不满足该形式的 border 长度 ,不妨设 。那么在 的长度为 的前缀中, 是它的一个 border,即 是这个前缀的周期,而 也是其周期,且因为 有 ,根据 Periodicity Lemma
有 是这个前缀的周期,同时 所以 是原串的一个周期,与 是 的最短周期长度不符。QED
根据推论我们可以知道如果 串不是满周期串(即可划分为若干个部分满足各个部分的字符串完全相同),那么 的所有 border 都可以正确构造,而构造 的时候将 的所有 border 都已经正确构造了,所以这样就是对的。
证明 不是满周期串是简单的:如果 是满周期串,不妨设 ,其中 是一个字符串。那么 是 最长的 border。而如果在原串中有这样的一个 border 且 是周期,那么可以立即导出 是周期,那么 就不是最小周期。
对于 4 情况,先递归进入 求解。设 ,那么我们需要确定一个字典序最小的字符串 满足 的最长 border 为 。
首先我们肯定希望 是全 的字符串。但是只有这一种选择显然不能覆盖所有的情况,比如 时这样会使得最长 border 变大导致构造不合法。考虑在什么情况下以全 串作为字符串 会导致不合法。不妨讨论有一个更长的 border :
- , 串在前面加若干个 等于在后面加若干个 ,可导出 是全 串。这种情况下可以选择若干个 后面加上一个 形成的字符串,这样就是最优。
- ,假设 是最大的非平凡 border 长度,那么它有一个长度为 的周期。又因为 也是它的周期,而 是最短周期,所以 是 的约数,也就是说 是一个周期串。此时 的情况 就是全零较为平凡,而在 的情况下,我们总可以把 表示为 形式,其中 是一个非全 的字符串,且 。设 为将 最后的 换成 得到的字符串,考虑把中间的 换成 之后得到的字符串 。设它存在长度 的 border ,不妨设长度为 :
-
- ,在 前面加上 和在后面加上 得到相同的字符串,可以导出 中一个字符需要既等于 又等于 ,不可能;
-
- ,我们称前面插 的串为串 ,后面插 的串为串 ,此时由两个字符串相等,可以知道 里的 会跟 里的 的一个长度为 的子串匹配。首先它一定不会是 ,否则这个 border 长度就是原串长度。同时 的最后一个字符(也就是 1)不能出现在 和 中。也就是说 的 一定在 里面匹配,假设匹配了 。这里再进行一些讨论:
-
-
- ,这意味着 的一段前缀 是跟 匹配的。注意到 里 后面紧跟着的就是 ,根据相等, 有一个长度为 的 border,而 的周期是 ,也就是说 的最后 个字符一定包含一个 。而在 里 前面的 个字符就是 的最后 个字符,它们在 里对应要相等的 个字符是 的前 个字符,因此必定有一个字符既是 0 又是 1,矛盾。
-
-
-
- ,跟上面基本相同,但还需要考虑到的事情是 可能恰好以 开头。这个时候转换一下目标, 里 后面的那个 的长度为 的后缀在 里对应相等的是 ,所以也会有一个字符既是 又是 ,矛盾。
-
-
-
- ,先不妨假设 里 匹配的 不是 里的第一个,这样它前面有一个 ,剩余情况是类似的。设 里 的前面 个字符构成的字符串是 ,那么 是 的一个周期,那么 的长度为 的后缀应该是 的一个 rotate(就是不断把最后一个字符丢到第一个做若干次得到的字符串)。同时可以发现 前面的 个字符对应到 上是 ,且它是 的一个后缀。也就是说 必定等于 的一个 rotate,但是可以发现这两个字符串 1 的个数都不一样显然不可能相等,矛盾。
-
至此可以得出将 的最后一个 换成 得到的串一定是合法的,而它显然是最优的。
梳理一下 的流程:
- 如果 中所有字符相同,返回 个 构成的字符串;
- 如果 周期集合为空,返回 个 接上 个 构成的字符串;
- 如果 最短的周期长度 满足 ,将 表示为 的形式,其中 是 的一个前缀,可为空,设 ,则返回 ;
- 如果 最短的周期长度 满足 ,设 。检验 的最长 border 是否为 ,若否将最后一个 替换为 ,然后将该串返回。
至于如何 check 全 串是否合法,暴力 KMP 一遍即可。由 可得复杂度为 。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】