1 条题解
-
0
自动搬运
来自洛谷,原作者为

xht
好想爱这个世界啊搬运于
2025-08-24 21:24:17,当前版本为作者最后更新于2020-02-22 20:48:46,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
怎么没人用 Lyndon 分解求最小表示法呢?它这么冷门的嘛...
Lyndon 串
对于一个字符串,若其本身就是其最小后缀,则称它为 Lyndon 串。
形式化地,对于长度为 的字符串 ,若满足对于 ,都有 ,则称其为 Lyndon 串。
Lyndon 分解
任意一个字符串都可以被唯一的分解成若干个字典序非严格递减的 Lyndon 串。
形式化地,对于长度为 的字符串 ,存在唯一的若干个 Lyndon 串 ,满足 且 。
Duval 算法
Duval 算法可以在 的时间求出一个字符串的 Lyndon 分解。
维护三个指针 ,这三个指针将整个字符串分成了四个部分 :
- :这部分的 Lyndon 分解已经完成。
- :这部分可以被表示成 ,其中 是一个 Lyndon 串, 表示 循环 次, 是 的一个可空真前缀。
- :注意这部分是包含在上一个部分中的,其中 。
- :这部分还未处理,此时正在考虑 。
考虑 有三种情况:
- :可以将 继续循环下去,因此 往后移一位,考虑下一个 。
- :可以将 合并为一个 Lyndon 串,因此 设为 ,考虑下一个 。
- :可以将 单独作为 Lyndon 分解中的一个串,然后从 的开头开始重新考虑,因此 设为 的开头, 对应设为 。
【模板】P6114 【模板】Lyndon 分解
const int N = 5e6 + 7; int n, ans; char s[N]; int main() { rds(s, n); int i = 1; while (i <= n) { int j = i, k = i + 1; while (k <= n && s[j] <= s[k]) j = s[j] == s[k++] ? j + 1 : i; while (i <= j) i += k - j, ans ^= i - 1; } print(ans); return 0; }最小表示法
一个字符串的最小表示定义为其所有循环同构中字典序最小的串。
形式化地,对于长度为 的字符串 ,若 满足对于 ,都有 ,则称 为 的最小表示。
最小表示法可以使用 Lyndon 分解求出。
对于长度为 的字符串 ,设 ,对 进行 Lyndon 分解,找到首字符位置 且最大的 Lyndon 串,这个串的首字符即最小表示法的首字符。
【模板】P1368 工艺 /【模板】最小表示法
const int N = 6e5 + 7; int n, ans, s[N]; int main() { rd(n); for (int i = 1; i <= n; i++) rd(s[i]), s[i+n] = s[i]; int i = 1; while (i <= n) { int j = i, k = i + 1; while (k <= n * 2 && s[j] <= s[k]) j = s[j] == s[k++] ? j + 1 : i; while (i <= j) i += k - j, ans = i <= n ? i : ans; } if (ans == 0) ans = n; for (int i = 1; i <= n; i++) print(s[ans-1+i], " \n"[i==n]); return 0; }【例题】UVA719 Glass Beads
与上一题不同的是,这题要求位置最靠前。
只有一种情况下两道题的答案不一样,那就是字符串恰好为一个循环串的时候。
那么我们换一个写法即可。
const int N = 2e4 + 7; int n, ans; char s[N]; inline void solve() { rds(s, n); for (int i = 1; i <= n; i++) s[i+n] = s[i]; int i = 1; while (i <= n) { ans = i; int j = i, k = i + 1; while (k <= n * 2 && s[j] <= s[k]) j = s[j] == s[k++] ? j + 1 : i; while (i <= j) i += k - j; } print(ans); } int main() { int T; rd(T); while (T--) solve(); return 0; }参考资料
- OI Wiki Lyndon 分解
- wucstdio 题解 P6127 【【模板】Lyndon 分解】
- 1
信息
- ID
- 366
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者