1 条题解

  • 0
    @ 2025-8-24 21:49:51

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Itst
    没钩选手瑟瑟发抖

    搬运于2025-08-24 21:49:51,当前版本为作者最后更新于2020-02-17 21:01:47,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    同步发布于cnblogs

    Updated On 2022.02.01:情况 4 细节添加,也算是解决了第一次做这个题的时候一些口胡上的疑惑


    2011年就能出出这样充满科技感+脑力的题,佩服POI Orz

    约定:字符串 ss 的下标从 00 开始,si,js_{i,j} 表示 ss 的第 ii 到第 jj 个字符构成的子串。

    ss 有长度为 ll 的周期等价于其有长度为 sl|s|-l 的 border。


    设函数 solve(s)solve(s) 表示字典序最小的、border 集合与 ss 的 border 集合相同的 0101 字符串。分为以下情况:

    1. 如果 ss 中所有字符相同,返回 s|s|00 构成的字符串;
    2. 如果 ss 周期集合为空,返回 s1|s| - 100 接上 1111 构成的字符串;
    3. 如果 ss 最短的周期长度 lenlen 满足 2lens2len \leq |s|,设 t=s1,lent = s_{1,len},则 ss 可表示为 ttt...ttttt...tt' 的形式,其中 tt'tt 的一个前缀,可为空。
    4. 如果 ss 最短的周期长度 lenlen 满足 2len>s2len > |s|,设 border 为 tt,那么 ss 就可以表示为 tattat 的形式,其中 aa 是一个任意字符串,不能为空。

    1 和 2 情况的构造是显然的。


    对于 3 情况,递归进入 tttt' 求解。设 qq=solve(tt)qq' = solve(tt'),那么就把 qq 重复若干次拼上 qqqq',即可得到答案。

    在证明正确性前先来复习有关周期和 border 的几个 OI 界众所周知的简单定理。

    • Weak Periodicity Lemma:对于一个字符串 ss,若其有长度为 pp 和长度为 qq 的周期,且 p+qsp+q \leq |s|,则 ss 有长度为 gcd(p,q)\gcd(p,q) 的周期。

    Proof. 设 p<qp < q,令 d=qpd = q - p。因为 p+qsp + q \leq |s|,所以 i[0,s1],ip0\forall i \in [0,|s|-1] , i - p \geq 0i+q<si+q < |s| 至少有一个成立,故可以先向后跳 qq 再向前跳 pp,或者先向前跳 pp 再向后跳 qq,可得 si+d=sis_{i+d} = s_i。那么 qpq-p 也是 ss 的周期。根据辗转相除法,gcd(p,q)\gcd(p,q) 也是 ss 的一个周期。QED

    • 一个推论:设 ss 最短周期长度为 ll,且 2ls2l \leq |s|,则 ss 的 border 集合中 l+(smodl)\geq l + (|s| \bmod l) 的元素一定构成集合 $\{pl + (|s| \bmod l) | p \in Z^+ , pl + (|s| \bmod l) \leq |s|\}$。

    Proof. 首先这些元素一定会包含在 border 集合内。考虑使用反证法证明不存在其他的元素。

    设有不满足该形式的 border 长度 ll',不妨设 l=xl+(smodl)+y(y[1,l1])l' = xl+(|s| \bmod l)+y(y \in [1,l-1])。那么在 ss 的长度为 (x+1)l+(smodl)(x+1)l + (|s| \bmod l) 的前缀中,ll' 是它的一个 border,即 lyl-y 是这个前缀的周期,而 ll 也是其周期,且因为 x1x \geq 1(x+1)l+(smodl)2ly(x+1)l + (|s| \bmod l) \geq 2l-y,根据 Periodicity Lemmagcd(l,ly)\gcd(l,l-y) 是这个前缀的周期,同时 gcd(l,ly)l\gcd(l,l-y) \mid l 所以 gcd(l,ly)\gcd(l,l-y) 是原串的一个周期,与 llss 的最短周期长度不符。QED


    根据推论我们可以知道如果 qq 串不是满周期串(即可划分为若干个部分满足各个部分的字符串完全相同),那么 qq\geq |qq'| 的所有 border 都可以正确构造,而构造 qqqq' 的时候将 <qq< |qq'| 的所有 border 都已经正确构造了,所以这样就是对的。

    证明 qq 不是满周期串是简单的:如果 qq 是满周期串,不妨设 q=pcq = p^c,其中 pp 是一个字符串。那么 qqp|qq'|-|p|qqqq' 最长的 border。而如果在原串中有这样的一个 border 且 qq 是周期,那么可以立即导出 pp 是周期,那么 qq 就不是最小周期。


    对于 4 情况,先递归进入 s1,lens_{1,len} 求解。设 t=solve(s1,len)t = solve(s_{1,len}),那么我们需要确定一个字典序最小的字符串 aa 满足 s=tats=tat 的最长 border 为 tt

    首先我们肯定希望 aa 是全 00 的字符串。但是只有这一种选择显然不能覆盖所有的情况,比如 t=0000t = 0000 时这样会使得最长 border 变大导致构造不合法。考虑在什么情况下以全 00 串作为字符串 aa 会导致不合法。不妨讨论有一个更长的 border ll

    • lt+al \leq |t| + |a|tt 串在前面加若干个 00 等于在后面加若干个 00,可导出 tt 是全 00 串。这种情况下可以选择若干个 00 后面加上一个 11 形成的字符串,这样就是最优。
    • l>t+al > |t| + |a|,假设 ll 是最大的非平凡 border 长度,那么它有一个长度为 2t+al2|t|+|a|-l 的周期。又因为 t+a|t|+|a| 也是它的周期,而 2t+al2|t|+|a|-l 是最短周期,所以 2t+al2|t|+|a|-lt+a|t|+|a| 的约数,也就是说 t+at+a 是一个周期串。此时 2t+ala2|t|+|a|-l \leq |a| 的情况 tt 就是全零较为平凡,而在 2t+al>a2|t|+|a|-l > a 的情况下,我们总可以把 tt 表示为 bab...babbab...bab 形式,其中 bb 是一个非全 00 的字符串,且 ba=2t+al|ba| = 2|t|+|a|-l。设 aa' 为将 aa 最后的 00 换成 11 得到的字符串,考虑把中间的 aa 换成 aa' 之后得到的字符串 ss'。设它存在长度 >t>|t| 的 border ,不妨设长度为 ll
      • l<t+al < |t| + |a'|,在 tt 前面加上 000...001000...001 和在后面加上 000...000000...000 得到相同的字符串,可以导出 tt 中一个字符需要既等于 00 又等于 11,不可能;
      • lt+al \geq |t| + |a|,我们称前面插 aa' 的串为串 ss,后面插 aa' 的串为串 tt,此时由两个字符串相等,可以知道 ss 里的 aa' 会跟 tt 里的 baba...babababa...baba' 的一个长度为 a|a| 的子串匹配。首先它一定不会是 aa',否则这个 border 长度就是原串长度。同时 aa' 的最后一个字符(也就是 1)不能出现在 aaaa' 中。也就是说 aa'11 一定在 bb 里面匹配,假设匹配了 bib_i。这里再进行一些讨论:
        • i<ai < |a|,这意味着 aa' 的一段前缀 00 是跟 aa 匹配的。注意到 ssaa' 后面紧跟着的就是 babab...babbabab...bab,根据相等,bb 有一个长度为 L=biL = |b| - i 的 border,而 bb 的周期是 000001000\cdots001,也就是说 bb 的最后 ii 个字符一定包含一个 11。而在 ssaa' 前面的 ii 个字符就是 bb 的最后 ii 个字符,它们在 tt 里对应要相等的 ii 个字符是 aa 的前 ii 个字符,因此必定有一个字符既是 0 又是 1,矛盾。
        • i=ai = |a|,跟上面基本相同,但还需要考虑到的事情是 ss 可能恰好以 aa' 开头。这个时候转换一下目标,ssaa' 后面的那个 bb 的长度为 a|a| 的后缀在 tt 里对应相等的是 aa,所以也会有一个字符既是 11 又是 00,矛盾。
        • i>ai > |a|,先不妨假设 ssaa' 匹配的 bb 不是 tt 里的第一个,这样它前面有一个 aa,剩余情况是类似的。设 ssaa' 的前面 iai-|a| 个字符构成的字符串是 cc,那么 caca'bb 的一个周期,那么 bb 的长度为 ii 的后缀应该是 caca' 的一个 rotate(就是不断把最后一个字符丢到第一个做若干次得到的字符串)。同时可以发现 aa' 前面的 ii 个字符对应到 tt 上是 acac,且它是 bb 的一个后缀。也就是说 acac 必定等于 caca' 的一个 rotate,但是可以发现这两个字符串 1 的个数都不一样显然不可能相等,矛盾。

    至此可以得出将 aa 的最后一个 00 换成 11 得到的串一定是合法的,而它显然是最优的。


    梳理一下 solve(s)solve(s) 的流程:

    1. 如果 ss 中所有字符相同,返回 s|s|00 构成的字符串;
    2. 如果 ss 周期集合为空,返回 s1|s| - 100 接上 1111 构成的字符串;
    3. 如果 ss 最短的周期长度 lenlen 满足 2lens2len \leq |s|,将 ss 表示为 ttt...ttttt...tt' 的形式,其中 tt'tt 的一个前缀,可为空,设 qq=solve(tt)qq' = solve(tt'),则返回 qslenqq^{\lfloor \frac{|s|}{len} \rfloor}q'
    4. 如果 ss 最短的周期长度 lenlen 满足 2len>s2len > |s|,设 t=s1,len,q=solve(t)t = s_{1,len} , q = solve(t)。检验 t+000...000+tt+000...000+t 的最长 border 是否为 lenlen,若否将最后一个 00 替换为 11,然后将该串返回。

    至于如何 check 全 00 串是否合法,暴力 KMP 一遍即可。由 T(n)=T(n2)+O(n)T(n) = T(\frac{n}{2}) + O(n) 可得复杂度为 O(n)O(n)

    • 1

    信息

    ID
    2602
    时间
    1000ms
    内存
    512MiB
    难度
    7
    标签
    递交数
    0
    已通过
    0
    上传者