后缀自动机XJ
后缀自动机初探(xiajiang)
后缀树\((Suffix Tree)\)
对于一个字符串,把它的所有后缀插入到\(Trie\)中就是一个后缀树。
当然字母存在边上,最终的点可以用一个特殊符号如:\(\&\)来表示这个后缀结束了。
考虑对树压缩路径,也就是把原字符串一个个后缀存到点上。
这样的话节点数就达到了\(O(N)\)级别。
然后就是啪啪的建树......这个过程不多做讲述......
我们现在假设你会建树,会dp,那么:
给定一个长度为\(n\)的字符串\(S\),记\(suf[i]\)表示从$ i $开始的后缀。
求:\(\sum_{1<=i<j<=n}len[suf[i]] + len[suf[j]] - 2 * lcp(suf[i],suf[j])\)
前面的话可以\(O(1)\)的算出来,关键是后面怎么算?(2*lcp(suf[i],suf[j])
两个节点的最长公共前缀就是LCA的后缀,然后处理出有多少个后缀包含当前节点字符串的前缀,树上背包就可以了。
其实后缀树就是可以使你维护字符串变得方便又高效。
后缀自动机\((Suffix Auto Maton)\)
前言:其实\(SAM\)好建,好做,不好想...
官定:
对给定字符串\(S\)的后缀自动机是一个最小化确定有限状态自动机,它能够接收字符串\(S\)所有后缀。
而且从初始状态0可以到达所有状态。
一个或多个状态被标记为终止状态。如果我们从初始状态0经由任意路径走到某一终止状态,并顺序写出所有经过边的标记,得到的字符串必然是\(s\)的某一后缀。
并且\(SAM\)维护以上顶点数最少。
留坑