约定:字符串 $s$ 的下标从 $0$ 开始,$s_{i,j}$ 表示 $s$ 的第 $i$ 到第 $j$ 个字符构成的子串。
串 $s$ 有长度为 $l$ 的周期等价于其有长度为 $|s|-l$ 的 border。
设函数 $solve(s)$ 表示字典序最小的、border 集合与 $s$ 的 border 集合相同的 $01$ 字符串。分为以下情况:
- 如果 $s$ 中所有字符相同,返回 $|s|$ 个 $0$ 构成的字符串;
- 如果 $s$ 周期集合为空,返回 $|s| - 1$ 个 $0$ 接上 $1$ 个 $1$ 构成的字符串;
- 如果 $s$ 最短的周期长度 $len$ 满足 $2len \leq |s|$,设 $t = s_{1,len}$,则 $s$ 可表示为 $ttt...tt'$ 的形式,其中 $t'$ 是 $t$ 的一个前缀,可为空。
- 如果 $s$ 最短的周期长度 $len$ 满足 $2len > |s|$,设 border 为 $t$,那么 $s$ 就可以表示为 $tat$ 的形式,其中 $a$ 是一个任意字符串,不能为空。
1 和 2 情况的构造是显然的。
对于 3 情况,递归进入 $tt'$ 求解。设 $qq' = solve(tt')$,那么就把 $q$ 重复若干次拼上 $qq'$,即可得到答案。
在证明正确性前先来复习有关周期和 border 的几个 OI 界众所周知的简单定理。
- Weak Periodicity Lemma:对于一个字符串 $s$,若其有长度为 $p$ 和长度为 $q$ 的周期,且 $p+q \leq |s|$,则 $s$ 有长度为 $\gcd(p,q)$ 的周期。
Proof. 设 $p < q$,令 $d = q - p$。因为 $p + q \leq |s|$,所以 $\forall i \in [0,|s|-1] , i - p \geq 0$ 和 $i+q < |s|$ 至少有一个成立,故可以先向后跳 $q$ 再向前跳 $p$,或者先向前跳 $p$ 再向后跳 $q$,可得 $s_{i+d} = s_i$。那么 $q-p$ 也是 $s$ 的周期。根据辗转相除法,$\gcd(p,q)$ 也是 $s$ 的一个周期。QED
- 一个推论:设 $s$ 最短周期长度为 $l$,且 $2l \leq |s|$,则 $s$ 的 border 集合中 $\geq l + (|s| \bmod l)$ 的元素一定构成集合 $\{pl + (|s| \bmod l) | p \in Z^+ , pl + (|s| \bmod l) \leq |s|\}$。
Proof. 首先这些元素一定会包含在 border 集合内。考虑使用反证法证明不存在其他的元素。
设有不满足该形式的 border 长度 $l'$,不妨设 $l' = xl+(|s| \bmod l)+y(y \in [1,l-1])$。那么在 $s$ 的长度为 $(x+1)l + (|s| \bmod l)$ 的前缀中,$l'$ 是它的一个 border,即 $l-y$ 是这个前缀的周期,而 $l$ 也是其周期,且因为 $x \geq 1$ 有 $(x+1)l + (|s| \bmod l) \geq 2l-y$,根据 Periodicity Lemma 有 $\gcd(l,l-y)$ 是这个前缀的周期,同时 $\gcd(l,l-y) \mid l$ 所以 $\gcd(l,l-y)$ 是原串的一个周期,与 $l$ 是 $s$ 的最短周期长度不符。QED
根据推论我们可以知道如果 $q$ 串不是满周期串(即可划分为若干个部分满足各个部分的字符串完全相同),那么 $\geq |qq'|$ 的所有 border 都可以正确构造,而构造 $qq'$ 的时候将 $< |qq'|$ 的所有 border 都已经正确构造了,所以这样就是对的。
证明 $q$ 不是满周期串是简单的:如果 $q$ 是满周期串,不妨设 $q = p^c$,其中 $p$ 是一个字符串。那么 $|qq'|-|p|$ 是 $qq'$ 最长的 border。而如果在原串中有这样的一个 border 且 $q$ 是周期,那么可以立即导出 $p$ 是周期,那么 $q$ 就不是最小周期。
对于 4 情况,先递归进入 $s_{1,len}$ 求解。设 $t = solve(s_{1,len})$,那么我们需要确定一个字典序最小的字符串 $a$ 满足 $s=tat$ 的最长 border 为 $t$。
首先我们肯定希望 $a$ 是全 $0$ 的字符串。但是只有这一种选择显然不能覆盖所有的情况,比如 $t = 0000$ 时这样会使得最长 border 变大导致构造不合法。考虑在什么情况下以全 $0$ 串作为字符串 $a$ 会导致不合法。不妨讨论有一个更长的 border $l$:
- $l \leq |t| + |a|$,$t$ 串在前面加若干个 $0$ 等于在后面加若干个 $0$,可导出 $t$ 是全 $0$ 串。这种情况下可以选择若干个 $0$ 后面加上一个 $1$ 形成的字符串,这样就是最优。
- $l > |t| + |a|$,假设 $l$ 是最大的非平凡 border 长度,那么它有一个长度为 $2|t|+|a|-l$ 的周期。又因为 $|t|+|a|$ 也是它的周期,而 $2|t|+|a|-l$ 是最短周期,所以 $2|t|+|a|-l$ 是 $|t|+|a|$ 的约数,也就是说 $t+a$ 是一个周期串。此时 $2|t|+|a|-l \leq |a|$ 的情况 $t$ 就是全零较为平凡,而在 $2|t|+|a|-l > a$ 的情况下,我们总可以把 $t$ 表示为 $bab...bab$ 形式,其中 $b$ 是一个非全 $0$ 的字符串,且 $|ba| = 2|t|+|a|-l$。设 $a'$ 为将 $a$ 最后的 $0$ 换成 $1$ 得到的字符串,考虑把中间的 $a$ 换成 $a'$ 之后得到的字符串 $s'$。设它存在长度 $>|t|$ 的 border ,不妨设长度为 $l$:
- $l < |t| + |a'|$,在 $t$ 前面加上 $000...001$ 和在后面加上 $000...000$ 得到相同的字符串,可以导出 $t$ 中一个字符需要既等于 $0$ 又等于 $1$,不可能;
- $l \geq |t| + |a|$,我们称前面插 $a'$ 的串为串 $s$,后面插 $a'$ 的串为串 $t$,此时由两个字符串相等,可以知道 $s$ 里的 $a'$ 会跟 $t$ 里的 $baba...baba'$ 的一个长度为 $|a|$ 的子串匹配。首先它一定不会是 $a'$,否则这个 border 长度就是原串长度。同时 $a'$ 的最后一个字符(也就是 1)不能出现在 $a$ 和 $a'$ 中。也就是说 $a'$ 的 $1$ 一定在 $b$ 里面匹配,假设匹配了 $b_i$。这里再进行一些讨论:
- $i < |a|$,这意味着 $a'$ 的一段前缀 $0$ 是跟 $a$ 匹配的。注意到 $s$ 里 $a'$ 后面紧跟着的就是 $babab...bab$,根据相等,$b$ 有一个长度为 $L = |b| - i$ 的 border,而 $b$ 的周期是 $000\cdots001$,也就是说 $b$ 的最后 $i$ 个字符一定包含一个 $1$。而在 $s$ 里 $a'$ 前面的 $i$ 个字符就是 $b$ 的最后 $i$ 个字符,它们在 $t$ 里对应要相等的 $i$ 个字符是 $a$ 的前 $i$ 个字符,因此必定有一个字符既是 0 又是 1,矛盾。
- $i = |a|$,跟上面基本相同,但还需要考虑到的事情是 $s$ 可能恰好以 $a'$ 开头。这个时候转换一下目标,$s$ 里 $a'$ 后面的那个 $b$ 的长度为 $|a|$ 的后缀在 $t$ 里对应相等的是 $a$,所以也会有一个字符既是 $1$ 又是 $0$,矛盾。
- $i > |a|$,先不妨假设 $s$ 里 $a'$ 匹配的 $b$ 不是 $t$ 里的第一个,这样它前面有一个 $a$,剩余情况是类似的。设 $s$ 里 $a'$ 的前面 $i-|a|$ 个字符构成的字符串是 $c$,那么 $ca'$ 是 $b$ 的一个周期,那么 $b$ 的长度为 $i$ 的后缀应该是 $ca'$ 的一个 rotate(就是不断把最后一个字符丢到第一个做若干次得到的字符串)。同时可以发现 $a'$ 前面的 $i$ 个字符对应到 $t$ 上是 $ac$,且它是 $b$ 的一个后缀。也就是说 $ac$ 必定等于 $ca'$ 的一个 rotate,但是可以发现这两个字符串 1 的个数都不一样显然不可能相等,矛盾。
至此可以得出将 $a$ 的最后一个 $0$ 换成 $1$ 得到的串一定是合法的,而它显然是最优的。
梳理一下 $solve(s)$ 的流程:
- 如果 $s$ 中所有字符相同,返回 $|s|$ 个 $0$ 构成的字符串;
- 如果 $s$ 周期集合为空,返回 $|s| - 1$ 个 $0$ 接上 $1$ 个 $1$ 构成的字符串;
- 如果 $s$ 最短的周期长度 $len$ 满足 $2len \leq |s|$,将 $s$ 表示为 $ttt...tt'$ 的形式,其中 $t'$ 是 $t$ 的一个前缀,可为空,设 $qq' = solve(tt')$,则返回 $q^{\lfloor \frac{|s|}{len} \rfloor}q'$;
- 如果 $s$ 最短的周期长度 $len$ 满足 $2len > |s|$,设 $t = s_{1,len} , q = solve(t)$。检验 $t+000...000+t$ 的最长 border 是否为 $len$,若否将最后一个 $0$ 替换为 $1$,然后将该串返回。
至于如何 check 全 $0$ 串是否合法,暴力 KMP 一遍即可。由 $T(n) = T(\frac{n}{2}) + O(n)$ 可得复杂度为 $O(n)$。