退役前的字符串学习

exkmp:

线性求出字符串的任何一个后缀与自身的lcp长度

设其为\(z\)数组,\(z[i]\)表示\([1,n]\)\([i,n]\)lcp的长度

考虑从前往后依次求出\(z[i]\)

考虑维护\(i+z[i]-1\)最大的\(j\)

那么如果\(i<=j+z[j]-1\),考虑\([i,j+z[j]-1]=[i-j+1,z[j]-1]\)

\(z[i]\)就从\(min(z[i-j+1],j+z[j]-i)\)继承过来即可

然后剩下的部分暴力往后匹配

注意你如果需要暴力往后匹配,\(j+z[j]-1\)必然会被当前的\(i+z[i]-1\)更新,每匹配一位就至少变大\(1\)

因为如果\(min(z[i-j+1],j+z[j]-i)=z[i-j+1]\)\(z[i]\)是不会更新的,因为两者一样的部分长于\(z[i-j+1]\)\(z[i]\)不会比\(z[i-j+1]\)

综上所述,复杂度是\(O(n)\)

一份含exkmp的代码code



lyndon words and runs

没有lemma的证明(有些没看懂)

lyndon串:一个满足除了本身以外的后缀,字典序都比它本身大的串

一个性质:两个lyndon串\(s,t\),若\(s\)严格小于\(t\),则\(st\)是lyndon串

一个串的lyndon分解:把一个串分解成\(s_1,s_2...s_k\),满足\(s_1,s_2...s_k\)都是lyndon串,且\(s_1 \geq s_2 \geq ... \geq s_k\),这里\(\geq\)表示字典序不小于

一个性质:一个串的lyndon分解存在且唯一

求lyndon分解:Duval's Algorithm

增量法构造lyndon分解

考虑我们当前已经有\([i,|S|]\)的lyndon分解,要求出\([i-1,|S|]\)的lyndon分解

考虑维护一个栈,栈中每个元素是一个lyndon串的结尾

栈中元素需要满足这些lyndon串不降

向栈中加入\(i-1\)

若当前\(s[i:st[top]] > s[st[top]+1:st[top-1]]\)

则这两个可以合并,弹出栈顶

runs:定义三元组\((i,j,p)\)是一个run,当且仅当\(s_{j+1}\neq s_{j-p+1},s_{i-1}\neq s_{i+p-1}\)\(p\)\([i,j]\)最小的出现至少两次的循环节。

求runs

求出以每个位置为左端点的最长lyndon子串

这个其实就是上面的算法里每一步添加以后的栈顶元素

runs的求解:

对于上面的每一个串\([l,r]\),以它的长度为周期,向左/右扩展到\(l',r'\),若\([l',r']\)的长度不小于\([l,r]\)长度的两倍,则\([l',r']\)是一个runs

求解的时候要把字符大小关系反过来再求一次lyndon word和runs,才能求出全部的

模板题code

posted @ 2021-06-06 16:35  deaf  阅读(96)  评论(0编辑  收藏  举报