Lyndon Word 学习笔记
【定义与性质】
Primitive Word(PW):没有循环节的字符串。
Lyndon Word(LW):字典序严格小于它所有 cyclic-shift 的字符串。
LW 有很多美妙的性质。记
定义一个新符号
-
严格小于 所有 cyclic-shift。这是定义。 -
若
,则 无 border。若
,则 ,则 ( 小于所有 cyclic-shift)。 ,同理可知 。矛盾。所以
无 border。 -
等价定义:
小于所有真后缀。记
的一个后缀为 , 。若
,反证法,如果 ,因为 无 border,所以 ,则 ,与 矛盾。若
,有 。证毕。
-
等价定义:
将 任意拆成 , 。( 非空)换句话说就是
的前缀小于后缀。 :证 。若 ,显然;否则 是 的前缀。设
,其中 。则 。因为前缀小于后缀, ,所以 。(注意 不可能是前缀)而
,显然有 。 : 。那么 小于每个真后缀。则
,有 。(第一个 是前缀关系,第二个是真后缀) -
记
。 。 :由上面的等价定义直接推出。 :尝试用 "小于每个真后缀" 证明。把所有真后缀
分类: 是 真后缀的、 、 是 真后缀。-
是 真后缀的。则 可以写成 的形式。 是 的真后缀。因为
,所以 没有 border 且 ,所以 ,所以 。 -
。若 ,显然成立;否则 是 的前缀,设 。因为 ,所以 ,(同时加 )所以 ,得证。 -
是 的真后缀。 。
证毕。
-
-
LW 的标准分解定理。若
,取 的最小真后缀 ,则 是 的最长 真后缀,且(记 ) 。证明:
若存在
。因为 ,知 ,我们就得到了一个比最小真后缀更小的真后缀,矛盾。因为
是最小真后缀,所以 小于所有 的真后缀,所以 。因为
,所以对于任意 的后缀 ,有 。因为 ,所以 ,所以 。 -
由 6 引申出一个
的递归定义法,就是每个长度 的 都能拆成两个 。
【Lyndon 分解】
定理:每一个字符串
存在性:
先把
唯一性:
反证法。考虑两种方案
不妨
因为
因为
所以
Lyndon 分解有它美妙的性质。记
-
是最小后缀。考虑
的一个后缀 ,如果 是 的后缀,因为 ,所以 会比它更小。而当
,其中 是 的一个后缀。 。 -
是最长的 后缀。 是最小后缀,所以任意比 长的后缀都有 这个更小的真后缀,非 。 -
是最长 前缀。记
, 是 的前缀。则 ,于是 有了一个更小的后缀。
【Duval 算法求 Lyndon 分解】
- 定义:准
。若 ,且 , 是 的前缀,则 是准 。
容易发现,准
引理:两字符
证明:
Duval 算法是一个能
在算法过程中,我们把字符串
黑色部分是已经输出的
蓝色部分是正在处理,尚未确定的部分。
红色部分是尚未处理的。
然后我们维护三个指针
-
。若 已经等于 了,新开一个 ;否则往 里加就好。 -
。把 一起作为一个新的 。 -
。输出 (变成 部分),令 指向 开头重新跑。
若
代码很短。
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int n;
string s;
int i, j, k;
int main() {
int ans = 0;
cin >> s;
n = s.size();
s = ' ' + s;
i = 1;
while (i <= n) {
j = i;
k = i + 1;
while (s[k] >= s[j]) {
if (s[k] == s[j])
j++;
else
j = i;
k++;
}
while (i <= j) {
ans ^= (i + (k - j) - 1);
i += k - j;
}
}
cout << ans << endl;
return 0;
}
【Lyndon 分解的各种应用】
求字符串的最小表示法
若对
引理:设
证明:考虑起点
-
。因为 ,所以 ,所以 (长度更长还小)。所以 。 -
,设 , 。有
,所以 。若
,显然;否则 是 的前缀。那么比
其实就是比 。如此循环下去,可以用归纳法到
,而 是最小后缀。
证完引理,回到原来的算法。在
要比较它们,也相当于比较对应开始位置在
Lyndon Word 生成算法/找后继
记
。要求按照字典序从小到大生成所有长度 ,字符集大小为 的 LW。
把字符集看作
而可以找到
-
截取
的前 个字符,记为 。(例如 ) -
删除
末尾连续的最大字符。(例如 ,删完之后 ) -
,就是 进制数意义下的。因为已经删完了末尾的最大字符,所以肯定不会进位。
例如
LW 计数
求
的 LW 个数。
可以等价到另外一个问题:项链计数,要求没有循环节,称这个为问题 1。
考虑问题 2:项链计数,允许有循环节。
记问题 1 的答案为
考虑集合
考虑集合
同时
考虑算
所以
推导一下。记
同时
待证明:经过一些运算,
所以
【利用 Duval 算法中间结果】
在跑 Duval 的过程中同步计算答案。
求每个前缀的最小后缀
记
-
,则 。可以类比着来看。 -
, 。 -
,这种情况不管,因为 回溯之后会处理的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!