Lyndon Word学习笔记
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学习笔记的更多相关文章
- Lyndon words学习笔记
Lyndon words 定义: 对于一个字符串\(S\),若\(S\)的最小后缀是其本身,则\(S\)为一个\(lyndon\)串; 记为\(S\in L\); 即: \[S \in L \begi ...
- VSTO学习笔记(八)向 Word 2010 中写入表结构
原文:VSTO学习笔记(八)向 Word 2010 中写入表结构 前几天公司在做CMMI 3级认证,需要提交一系列的Word文档,其中有一种文档要求添加公司几个系统的数据库中的表结构.我临时接到了这项 ...
- C# 动态生成word文档 [C#学习笔记3]关于Main(string[ ] args)中args命令行参数 实现DataTables搜索框查询结果高亮显示 二维码神器QRCoder Asp.net MVC 中 CodeFirst 开发模式实例
C# 动态生成word文档 本文以一个简单的小例子,简述利用C#语言开发word表格相关的知识,仅供学习分享使用,如有不足之处,还请指正. 在工程中引用word的动态库 在项目中,点击项目名称右键-- ...
- 2015.05.15,外语,学习笔记-《Word Power Made Easy》 01 “如何讨论人格特点”
2015.03.17,外语,读书笔记-<Word Power Made Easy> 01 “如何讨论人格特点”学习笔记 SESSIONS 1 本来这些章节都是在一两年前学习的,现在趁给友人 ...
- SpringBoot学习笔记-Chapter2(hello word)
开篇 第一次在博客园上写博客,初衷是想记录一下学习笔记,以往都是用笔去记录下学习笔记,现在来看在效率.检索速度上以及可可复制性都不好.作为一名Java开发人员 不会Spring Boot一定会被鄙视的 ...
- DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记
今天要学习的这篇文章写的算是比较早的了,大概在DX11时代就写好了,当时龙书11版看得很潦草,并没有注意这篇文章,现在看12,觉得是跳不过去的一篇文章,地址如下: https://msdn.micro ...
- react-native学习笔记--史上最详细Windows版本搭建安装React Native环境配置
参考:http://www.lcode.org/react-native/ React native中文网:http://reactnative.cn/docs/0.23/android-setup. ...
- CSS3与页面布局学习笔记(八)——浏览器兼容性问题与前端性能优化方案
一.浏览器兼容 1.1.概要 世界上没有任何一个浏览器是一样的,同样的代码在不一样的浏览器上运行就存在兼容性问题.不同浏览器其内核亦不尽相同,相同内核的版本不同,相同版本的内核浏览器品牌不一样,各种运 ...
- 烤鸭的Source Insight学习笔记
如果你觉得这网页排版不好看,可以去下载我上传的word版:<烤鸭的Source Insight学习笔记.doc> http://download.csdn.NET/detail/benka ...
随机推荐
- 请求ajax失败的原因(进入到error)
原因: dataType 定义类型和返回类型不一致,我定义的json格式数据. {data:[],num:0} 这种是不规则的字符串,不是严格的json格式 应该改成{"data" ...
- [Swift]LeetCode112. 路径总和 | Path Sum
Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all ...
- PHP实现用户注册并保存数据到文件
首先我们实现功能时,分析实现的步骤是什么,就这个而言,我们应该接收用户提交的数据并进行校验,然后保存在文件,最后给用户反馈. 这里需要注意的是为了避免嵌套过深,这里使用自定义函数来实现,其代码如下: ...
- Data - Tools
数据工具汇总 史上最全的大数据分析和制作工具 全球100款大数据工具汇总 SQL 数据分析常用语句 01 - NumPy HomePage:http://www.numpy.org/ NumPy(数值 ...
- 为什么公司宁愿 25K 重新招人,也不给你加到 20K?原因太现实……
年底了,还有几天就要过年了,年后必定又是一波跳槽季,我们为什么要跳槽,为什么公司不能满足我们加薪的需求? 说到这个话题,想必从事码农的各位都清楚的一个道理:工资都是跳出来的,其他行业我不太清楚,但在 ...
- php的四个fetch语句
先给一个表 man: |---------------| |-name--|-age--| |--AA---|--aa---| |--BB---|--bb---| |--CC---|--cc---| ...
- Nginx学习系列三Nginx的启动、停止、修改配置文件后重启
1.启动Nginx 命令规则:Ngxin的安装地址 -c Nginx的安装地址下的配置文件地址 注意:一般都在root权限下进行Nginx的启动 2.停止Nginx (1).从容停止 第一步:查看Ng ...
- @@ITENTITY
@@identity是表示的是最近一次向具有identity属性(即自增列)的表插入数据时对应的自增列的值,是系统定义的全局变量.一般系统定义的全局变量都是以@@开头,用户自定义变量以@开头.sele ...
- Quartz.NET学习笔记(四) 计划任务触发器
通常来说计划任务触发器会比简单触发器的使用频率高很多.如果你的任务是需要基于日历每天定时运行,那你就应该使用计划任务触发器,例如每周五中午12:00执行任务,或者每天早上9点执行任务. 计划任务表达式 ...
- C++版 - Lintcode 77-Longest Common Subsequence最长公共子序列(LCS) - 题解
版权声明:本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C++版 - L ...