Lyndon Word

定义:对于字符串\(s\),若\(s\)的最小后缀为其本身,那么称\(s\)为Lyndon串

等价性:\(s\)为Lyndon串等价于\(s\)本身是其循环移位中最小的一个

性质

任意字符串\(s\)都可以分解为\(s = s_1 s_2 \dots s_k\),其中\(\forall s_i\)为Lyndon串且\(s_i \geqslant s_{i +1}\)。且这种分解方法是唯一的

  • 存在性

引理1:若\(u, v\)为Lyndon串,且\(u < v\),那么\(uv\)为Lyndon串

证明:
要证明\(uv\)为Lyndon串只需证明\(uv\)本身为其最小后缀,
我们可以把所有的后缀分为两类,一类是由\(u\)的后缀加上\(v\)串的来,这部分的相对大小不会改变。
另一类是\(v\)串的后缀,因为\(v\)本身也是Lyndon串,我们只需证明\(v > uv\),因为\(v > u\),显然成立

  • 唯一性

证明:
设\(pre(s, i)\)表示串\(s\)中\(s[1 \dots i]\)所代表的前缀
若有两种方案,取第一次不同的位置,设\(|s_i| > |s'_i|\)
令\(s_i = s'_i s'_{i + 1} \dots s'_{k} pre(s_{k + 1}, l)\)
反证法。根据定义,\(s_i < pre(s'_{k + 1}, l) \leqslant s'_{k + 1} \leqslant s'_i < s_i\)
矛盾

Duval算法

(下面内容抄袭并补充自参考资料2)

该算法可以在\(O(n)\)的时间内求出串\(s\)的Lyndon分解

测试地址

引理2:若字符串\(v\)和字符\(c\)满足\(vc\)是某个Lyndon串的前缀,则对于字符\(d>c\)有\(vd\)是Lyndon串

证明:和上面同样的思路,对于\(d\)之前的后缀相对大小不会改变,之后的后缀只会变大

该算法中我们仅需维护三个变量\(i, j, k\)

\(s[1..i - 1] = s_1 s_2 \dots s_g\)是固定下来的分解,也就是\(\forall l \in [1, g] s_l\)是Lyndon串且\(s_l > s_{l + 1}\)

\(s[i .. k - 1] = t_1 t_2 \dots t_h v(h > 1)\) 是没有固定的分解,满足\(t_1\)是Lyndon串,且\(t_1 = t_2 = \dots = t_h\),\(v\)是\(t_h\)的(可为空的)真前缀,且有\(s_g > s[i .. k - 1]\)

当前读入的字符是\(s[k]\),令\(j = k - |t_1|\)

分三种情况讨论

  • 当\(s[k] = s[j]\)时,周期\(k - j\)继续保持

  • 当\(s[k] > s[j]\)时,合并得到\(t_1 <- t_1 t_2 \dots t_h v s[k]\)是Lyndon串

  • 当\(s[k] < s[j]\)时,\(t_1, t_2, \dots, t_h\)的分解被固定下来,算法从\(v\)的开头处重新开始

#include<bits/stdc++.h>
using namespace std;
const int MAXN = (1 << 21) + 1;
char s[MAXN];
int main() {scanf("%s", s + 1);int N = strlen(s + 1), j, k;for(int i = 1; i <= N;) {j = i; k = i + 1;while(k <= N && s[j] <= s[k]) {if(s[j] < s[k]) j = i;else j++;k++;}while(i <= j) {printf("%d ", i + k - j - 1);i += k - j;}}return 0;
}

参考资料

Lyndon word

金策—字符串选讲

转载于:https://www.cnblogs.com/zwfymqz/p/10198690.html

Lyndon Word学习笔记相关推荐

  1. C++操作Word学习笔记(三)

    [当前博文转自http://blog.csdn.net/sgdgoodboy/article/details/2102628] [本文不只有Word相关内容,还涉及了Excel,由于字数限制,Exce ...

  2. Word学习笔记-使用技巧

    学习资源来自: 网易云课堂: 1小时玩转职场WORD https://study.163.com/course/courseMain.htm?courseId=1003075007 资深应用达人教你职 ...

  3. Word学习笔记:P1-页面简介文字编辑

    文章目录 前言 一.页面简介 二.文字编辑 前言 学习课程为 PAPAYA电脑教室 的Word课程. 课程与课件链接:课程链接.练习档案 一.页面简介 Word的界面如下所示,最上方为功能区. 初学者 ...

  4. Word学习笔记-项目实战

    学习资源来自: 1.公众号:Wordlm123,[办公必备]-[Word高手秘籍] 2.网易云课堂:Word2016五步搞定标准化试卷 https://study.163.com/course/cou ...

  5. Word学习笔记:P6-文档封面、页眉、页脚设置

    文章目录 一.文档封面设计 二.页眉.页脚设置 一.文档封面设计 今天我们需要插入一张图片作为封面,此时我们需要将第一页空出来.有的人会将鼠标移动到第一页标题的开头,然后一直按Enter键,直到第一页 ...

  6. Word学习笔记分享

    第一章.Word 的常规排版 1-5 文字选择 Ctrl+鼠标选取--多选 Alt+鼠标选取--框选 1-11 文字效果 为文字添加填充与边框 1-13 字体其他效果 为字体添加着重号.删除线.上下标 ...

  7. Word学习笔记:P5-标尺和定位点要如何使用

    文章目录 一.标尺 二.制表符 一.标尺 标尺的作用是针对段落进行缩进设定,它位于Word文字区域的上方.如果你的Word没有,可以在视图中将其打开.标尺左边从上到下有三个按钮:首行缩进.悬挂缩进和左 ...

  8. Word学习笔记:P10-你应该知道的Word表格技巧(上)

    文章目录 一.Word表格技巧 1.1 插入表格 1.2 调整表格 1.2.1 调整行高与列宽 1.2.2 删除内容 1.2.3 移动行和列 1.3 表格模板 1.4 表格公式 一.Word表格技巧 ...

  9. lyndon分解学习笔记

    Problem - H - Codeforces 假模板题,b站看jls用一个叫lyndon分解的神仙算法秒杀了此题,于是去学了lyndon分解,结果自己写完发现随便造了个数据就hack掉了(顺便去b ...

  10. C++操作Word学习笔记(一)

    [当前博文转载自:http://www.cppblog.com/codeart/archive/2010/08/31/125430.aspx] c++操作word接口 注意事项:1多用Range,少用 ...

最新文章

  1. 使用选择排序和二分查找在数组中查找数据
  2. Zookeeper源码用ant进行编译为eclipse工程--转载
  3. 浅谈Spring IOC和DI及Spring工厂类
  4. win7下wifi密码的保存路径
  5. ERROR: Failed to Setup IP tables: Unable to enable SKIP DNAT rule
  6. Linux硬链接与软链接的区别
  7. MacOS自定义设置定时开关机?
  8. 深度学习入门之二阶段小demo练习(持续更新系列)
  9. 如何做出3blue1brown的动画视频
  10. 5个不为人知的音乐网站,全网音乐免费听!说什么也不能错过
  11. 算力测试Linux,附录:计算力的标准Linpack测试详细指南(1)
  12. BGP路由技术详解(一)
  13. 操作系统课设详细解答
  14. 天耀18期 -09.数组-排序【作业】.doc
  15. 【Android】【打开方式】Android11用其它应用打开微信文件
  16. html中的matrix属性,transform,matrix属性讲解
  17. 云计算的定义是什么?
  18. 高效算法,B*寻路算法,python版,思维优化(1)
  19. 手抛飞机大改装(4种机型,7种改法)干货!!
  20. matlab中cla和clf作用,28377中CLA初始化部分不明白Cla1Task1和cla1Isr1的区别

热门文章

  1. 【钢铁缺陷检测算法】数据探索
  2. 【Python实例第28讲】核主成分
  3. Baxter实战 (五)安装openNI2,NiTE-2并实现kinect 2实现动作跟随
  4. 数组排序:冒泡法和选择法
  5. HDU 4455 Substrings(线性dp,很有意思)
  6. dubbo源码解析-spi(一)
  7. day03-PyCharm的设置与使用
  8. java基础语法day03
  9. 必做作业三:原型化系统-社区分享app
  10. 【面向对象设计原则】之开闭原则(OCP)