残缺笔记。超临界态!
Lydonn!!!
Lyndon Tree
Runs
定义 -1
周期、循环节:全部指的是不完整循环节,有时我也会说非严格循环节。
本原串:若一个字符串 \(s\),其不存在长度 \(<|s|\) 的周期,那么称其为本原串。
定义 0(Period)
若整数 \(p\) 是 \(s\) 的 period,当且仅当 \(s\) 存在一个长度为 \(p\) 的非严格循环节。
定义 1(Runs)
若三元组 \(r=(i,j,p)\) 为字符串 \(w\) 的一个 run,当且仅当 \(w[i\dots j]\) 的最小 period \(p\) 满足 \(2p\leq|w[i\dots j]|\),并且该周期性质不能再往左右延伸。也就是说,\(w[i\dots j+1]\) 与 \(w[i-1\dots j]\) 都不应具有 period \(p\)。
实数 \(\frac{j-i+1}{p}\) 被称为 \(r\) 的指数。
定义 2(Lyndon Word)
非空字符串 \(w\) 被称为一个关于 \(<\) 的 Lyndon Word,当且仅当 \(w<u\) 对于任意一个 \(w\) 的严格后缀 \(u\) 都成立。
易知这样的一个 \(w\) 不存在 \(<|w|\) 的 period。
容易发现,这个条件和 \(w\) 是 Lyndon Word 是等价的:\(w\) 在它的所有循环移位中,是字典序严格最小的。
一个字符串存在一个严格最小的循环移位,当且仅当它存在一个循环移位是本原串。
引理 3
令 \(w=u^ku'a\),其中 \(u\) 是一个 Lyndon Word,\(u'\) 是一个 \(u\) 的严格前缀(可以为空),\(k\) 为正整数,\(a\) 是一个不等于 \(u[|u'|+1]\) 的字符。
也就是说,令 \(A=u^{+\infty}\),\(S=\{u^k,k\in N^{+}\}\),那么 \(w\) 应当满足 \(w[1,|w|-1]\) 是 \(A\) 的前缀且 \(w\) 不是。并且 \(w\notin S\)。并且 \(|w|\geq |u|+1\)。
如果 \(u[|u'|+1]<a\),那么 \(w\) 是一个 Lyndon Word。否则 \(u\) 是任意一个以 \(w\) 为前缀的字符串的最长 Lyndon Word 前缀。
证明比较显然。貌似知道了这个就可以进行字符串的 Lyndon 分解了。
定义 4(Lyndon Root)
令 \(r=(i,j,p)\) 是字符串 \(w\) 的一个 run,长度为 \(p\) 的区间 \(\lambda=[i_{\lambda}\dots j_{\lambda}]\) 被称为 \(r\) 关于 \(<\) 的 Lyndon Root,当且仅当 \(i\leq i_{\lambda}\leq j_{\lambda}\leq j\),并且 \(w[i_{\lambda}\dots j_{\lambda}]\) 是一个关于 \(<\) 的 Lyndon Word。
对于任意的一组 \(r\) 和 \(<\),\(r\) 均存在一个 Lyndon Root。
这有点显然啊。在这个 run 里,长度为 \(p\) 的区间可以选到 \(w[i\dots j]\) 的长度为 \(p\) 的非严格循环节的全部循环移位。然后字典序严格最小的那一个一定是个 Lyndon Word。
The Runs Theorem
其实这个并不重要。而且我不会。
其实在计算 Runs这个部分稍微悄悄地提了一嘴。
引理 11
对于任意两个 Lyndon Word \(u\) 和 \(v\),若 \(u<v\),则 \(uv\) 也是个 Lyndon Word。
进行一个 Lyndon Word 的判定。
- 假如后缀 \(s\) 是 \(v\) 的严格后缀。
\(v<s\)。然后 \(u<v\),所以 \(u<s\)。所以 \(uv<s\)。 - 假如后缀 \(s=v\)。
\(u<v\)。\(u<s\)。所以 \(uv<s\)。 - 假如后缀 \(s=u'v\),其中 \(u'\) 为 \(u\) 的严格后缀。
\(u<u'\)。\(u<s\)。\(uv<s\)。
显然是对的。
引理 12
将字符串 \(s\) 分解成若干个 Lyndon Word,设其为 \(f_1,f_2,\dots,f_m\),且满足 \(f_1\geq f_2\geq\cdots\geq f_m\),那么这样的分解一定存在且唯一。
-
存在性:
贪心分解,每次找最长的 Lyndon Word。这样的分解一定存在,现在只需要证明大小关系。假设 \(f_i<f_{i+1}\),那么由引理 11,\(f_if_{i+1}\) 也是个 Lyndon Word。于是这个分解就不是最贪心的,矛盾。存在性得证。 -
唯一性:
尝试证明对于任意合法分解,\(f_1\) 是 \(s\) 的最长 Lyndon Word 前缀。
假如有前缀 \(x\) 是 Lyndon Word,且满足 \(|x|>|f_1|\)。令 \(x=f_1f_2\dots f_{k-1}y\)。其中 \(y\) 是 \(f_k\) 的前缀。所以有 \(y\leq f_k\)。又因为分解的性质,易得 \(y\leq f_1\)。那么 \(x\) 是 Lyndon Word,所以 \(x<y\leq f_1\),即 \(x<f_1\)。但 \(f_1\) 是 \(x\) 的前缀,因此 \(f_1\leq x\)。矛盾。结论得证。
直接归纳法,发现分解唯一。唯一性得证。
Lyndon 分解
为了实现 Lyndon 分解(即引理 12 中的分解),我们可以使用 Duval 算法。然而我不会。所以我们可以使用 pdf 中的做法。这样方便建树吧大概。
(pdf 中 \(<_0\) 就是普通的小于,\(<_1\) 就是将字符集大小反转后的小于。初看可能会觉得 \(<_1\) 就是 \(>\),但它其实并不是,原因显然。下文都讨论 \(<_0\) 情况下的做法。)
对于字符串 \(s\),设 \(l_i\) 表示最大的 \(j\),满足 \(s[i\dots j]\) 为 Lyndon Word。
直接从后往前找,维护一个后缀的 Lyndon 分解。具体地,栈里面若干个区间 \([l_i,r_i]\),分别代表当前的 \(f_i\)。当新加入一个 \(c\) 时,将 \(c\) 对应的长度为 \(1\) 的区间放入栈顶。此时,栈里面全部都是 Lyndon Word,于是可以直接通过引理 11,比较栈顶的两个子串来尝试进行合并。如果合并不了,就停下,此时一定满足分解的大小关系。
这是一个单调栈,比较次数 \(O(n)\)。
为什么某个后缀的 Lyndon 分解一定可以延伸到前面呢?为什么不会出现 \(f'_1=cf_1v\),其中 \(v\) 是 \(f_2\) 的严格前缀的情况呢?
证明其实很显然。容易发现 \(v<f_2\)。因为合并结束,所以 \(cf_1\geq f_2>v\)。
那么 \(f'_1\) 显然不是 Lyndon Word,得证。
根据引理 13,比较子串可以比较后缀啥的,因为有特殊性质。然而我并不打算证明引理 13。况且,知道了引理 13,我们也需要使用 \(O(n)-O(1)\) RMQ,还有 SA-IS 啥的来做到线性复杂度,有点垃圾。所以呢直接二分+哈希或者倍增求 SA 就可以做到 \(O(n\log n)\) 了。
哦哦。这样啊。因为我们求出了每个后缀的 Lyndon 分解,所以我们能求出 \(l_i\)。然后 Duval 算法并不行。真是太酷炫了。
计算 Runs
引理 7 表明,任何 Lyndon Root 恰好对应着某个 \([i,l_i]\)。这真是太酷炫了,因为我根本就没有证明引理 7。所以我们直接使用吧。
实际上,引理 8 表明,\(Beg(B_{r_1})\cap Beg(B_{r_2})=\varnothing\)。有了这个就可以简单地证明,run 的个数和 run 的指数和都是 \(O(n)\) 的了。具体可以看 pdf。
需要注意的是,一个 run 只对应一种序下的 Lyndon Root,这就是我们需要计算 \(l_0\) 和 \(l_1\) 的原因。其中 \(l_0\) 是使用 \(<_0\) 序的 \(l\),\(l_1\) 是使用 \(<_1\) 序的 \(l\)(这个在 Lyndon 分解里说过了)。于是上述分解要跑两遍或者维护两个栈才能求出所有的 run。
求 run 相当简单,所以我就不写了。哈哈哈。
一些简单的推论
推论 1
字符串 \(s\) 的任何 Lyndon 子串都不可能跨过其 Lyndon 分解。
证明很简单。设 \(x=af_{i+1}\dots f_{j-1}b\),其中 \(a\) 是 \(f_i\) 的非空后缀,\(b\) 是 \(f_j\) 的非空前缀,且 \(x\) 是 Lyndon Word。易知:
- \(b\leq f_j\)。
- \(a\geq f_i\)。
- \(f_i\geq f_j\)。
所以 \(a\geq f_i\geq f_j\geq b\)。因此 \(a\geq b\)。
若 \(a=b\),\(x\) 不是 Lyndon Word。
若 \(a>b\),\(x\) 不是 Lyndon Word。
矛盾了。原推论得证。
显然有个推推论:字符串 \(s\) 的最长 Lyndon 子串的长度为 \(\max\limits_{i=1}^m|f_i|\)。
推论 2
设字符串 \(s_1\) 的 Lyndon 分解为 \([f_1,f_2\dots f_{m_1}]\)。
设字符串 \(s_2\) 的 Lyndon 分解为 \([g_1,g_2\dots g_{m_2}]\)。
那么我们可以直接算出 \(s_1s_2\) 的 Lyndon 分解。
直接把 \(s_1\) 的 Lyndon 分解倒序放入 \(s_2\) 的栈里就可以了。
也就是说有 \([f_1,f_2\dots f_{m_1},g_1,g_2\dots g_{m_2}]\)。然后我们把它用引理 11 合并就可以了。
正确性显然。因为 Lyndon 分解唯一。
Palindrome
例题:求将字符串 \(S\) 划分为若干不交回文子串的方案数/最小回文子串个数。
朴素算法:直接做 DP!!!\(O(n^2)\)。
(一些非常简单的)Border 理论
引理 0
若字符串 \(S\) 有 Border 长度为 \(p\),那么其有周期长度为 \(|S|-p\)。
引理 1
回文串的回文后缀和其 Border 等价。
Periodicity Lemma(引理 2)
若一个串 \(S\) 有 \(p,q\) 两个周期,且 \(p+q-\gcd(p,q)\leq |S|\),则 \(\gcd(p,q)\) 也是 \(S\) 的周期。
证明:我不会。
Weak Periodicity Lemma(WPL,引理 3)
若一个串 \(S\) 有 \(p,q\) 两个周期,且 \(p+q\leq |S|\),则 \(\gcd(p,q)\) 也是 \(S\) 的周期。
证明思路:若 \(p>q\),可以尝试证明 \(r=p-q\) 为周期。
引理 4
字符串 \(S\) 的所有长度 \(\geq \frac{|S|}{2}\) 的 Border 的长度构成一个等差数列。
证明:使用 WPL。
设字符串 \(S\) 的最长 Border 长度为 \(a\),且 \(a\geq \frac{|S|}{2}\),则 \(S\) 的最小正周期 \(p=|S|-a\leq \frac{|S|}{2}\)。
设字符串 \(S\) 有一个长度为 \(b\) 的 Border,且 \(a>b\geq \frac{|S|}{2}\),那么 \(S\) 还有周期 \(q=|S|-b\leq \frac{|S|}{2}\)。
因此,\(p+q\leq |S|\)。使用 WPL,得到 \(d=\gcd(p,q)\) 也为周期。
又因为 \(p\) 是最小正周期,所以 \(d=p\)。所以 \(q=kp\),且 \(k\geq 2\)。
因此,\(b=|S|-q=|S|-kp=(|S|-p)-(k-1)p=a-(k-1)p\geq \frac{|S|}{2}\)。
也就是说任意满足长度满足条件的 \(b\),都一定能被表达成这个形式。现在我们只要证明,取值范围内的任何 \(k\) 都对应一个 Border 就行了。
因为 \(b=|S|-kp\geq \frac{|S|}{2}\),所以 \(2\leq k\leq \frac{|S|}{2p}\)。
任何一个 \(k\) 对应的 \(b\),都满足 \(b=|S|-kp\)。又因为的确有周期 \(kp\),所以 \(b\) 一定是个 Border。而且因为 \(kp\leq \frac{|S|}{2}\),所以 \(b\geq \frac{|S|}{2}\) 一定成立。综上,原引理得证。
设 \(m=\lfloor \frac{|S|}{2p}\rfloor\),则可以列出这些 Border 的长度:
这的确是等差数列。
引理 5
字符串 \(S\) 的所有 Border 可以被划分为 \(O(\log)\) 个等差数列。
证明:
使用引理 4。先划分出长度 \(\geq \frac{|S|}{2}\) 的 Border。
对于最长的长度小于等于 \(\frac{|S|}{2}\) 的 Border,它的 Border 再加上它本身就是原来字符串剩下的 Border。于是可以再用一遍引理 4,将当前 Border 长度除以 \(2\)。
这个过程只会进行 \(O(\log)\) 轮,因此有 \(O(\log)\) 个等差数列。
原引理得证。
引理 6(About PAM)
考虑在使用了引理 5 的等差数列划分的情况下,若建立 PAM 已经遍历到了字符串的 \(i\) 位置,当前在节点 \(x\),且 \(fail_x\) 和 \(x\) 在同一个等差数列,那么 \(fail_x\) 上次出现的右端点一定是 \(i-(Len_x-Len_{fail_x})\)。
证明可以考虑反证。假如不是,那么 \(i\) 会有更长的回文前缀,也就是说它有更长的 Border。然后就矛盾了。
PalindromePalindrome
https://codeforces.com/problemset/problem/2164/H 。
很好的题目。让我自己思考的话,可以想出两种情况分开处理。本以为分离的情况是 \(O(n)\) 的,结果被我自己举出反例了。但还是大概摸到了一点门槛吧。
分析 0
发现问题和区间最长出现至少两次的子串长度不一样。因为回文串不能半路截断。
分析 1
简单想一想,发现可以将两个回文串变成一个回文串。更准确地说,由于任何一个回文串的任何一个 Border 都是回文串,所以答案必定包含这一部分:区间 Border 最长/回文子串/的 Border 长度。因为我是受到两个回文串重叠的情况启发得到的这个结论,所以我把这种情况成为重叠情况。然而,事实上除了重叠,这还可以处理到 \(ABA\) 的情况,其中 \(A\) 和 \(ABA\) 都是回文串。因此叫重叠是不严谨的。但我就要这么叫。
分析 2
若有回文串 \(A\),非回文串 \(C\),则 \(ACA\) 我们也应该统计。这就是分离情况。考虑构造 PAM 的过程,我们在加入 \(c_i\) 后,得到了若干个以 \(i\) 结尾的回文后缀。根据引理 \(6\),可以发现,设最长回文后缀长度为 \(Len\),那么长度 \(<Len\) 且 \(\geq \frac{Len}{2}\) 的回文后缀的上次出现一定会被重叠情况统计到。也就是说它对我们没用了,可以只将 \(Len\) 考虑到分离情况内。但长度 \(<\frac{Len}{2}\) 的长度最大的回文后缀又是有用的了。于是长度每次减半,所以我们只会得到 \(O(\log n)\) 个可能在分离情况有贡献的回文后缀。
对于这些回文后缀,我们只要找到它们的上一次出现位置就行了。这个可以 fail 树上链覆盖单点查,不再赘述。于是这里变成了一个点数为 \(O(n\log n)\) 的二维数点问题。可以做到 \(O(n\log^2n)\) 的复杂度。
分析 3
处理重叠情况。最开始我以为这是简单的,后来发现我连区间最长回文子串长度都不会求。
实际上,区间最长回文串的做法可扩展性比较低。而且如果一定要在回文串上套数点的话,怎么想都会有很多维偏序,所以我们一般不直接考虑。
那怎么办呢?只能找性质了。想办法去掉各种限制,用错解不优思想或者其它更优雅的方式。

浙公网安备 33010602011771号