Day62:HDU1403-Longest Common Substring-后缀自动机SAM-最长公共子串
我的学习博客:
我觉得最好的就是它:https://www.luogu.com.cn/blog/Kesdiael3/hou-zhui-zi-dong-ji-yang-xie
http://hihocoder.com/problemset/problem/1441
以上两篇结合看
此外参考:
https://oi-wiki.org/string/sam/
kuangbin的:https://www.cnblogs.com/kuangbin/p/3309059.html
陈立杰讲稿:https://wenku.baidu.com/view/a97d51020129bd64783e0912a216147916117e1e.html
cf的,自己翻译吧https://codeforces.com/blog/entry/20861
比较多的题目和题解:https://www.cnblogs.com/zinthos/p/3899679.html
http://hihocoder.com/problemset 搜后缀自动机即可
洛谷的:http://hihocoder.com/problemset
知乎的://zhuanlan.zhihu.com/p/25948077
自己看吧
补充题目:
spoj 1811/hdu1403 Longest Common Substring --> 求两个串的最长公共子串
spoj 1812 Longest Common Substring II --> 求多个串的最长公共子串
后缀自动机英文:Suffix Automaton,简称SAM
时间复杂度:都是线性的
能够识别字符串所有后缀的自动机,也可以识别所有的子串
一般来说,能用后缀自动机解决的问题都可以用后缀数组解决。
HDU1403的题意:两个字符串的最长公共子串
思路:
第一个串A进行SAM函数,对其子串进行处理;
枚举第二个串B的前缀,判断该前缀的后缀是否出现在A中;(需要记录前缀最后的状态、前缀能匹配到的后缀的长度len)(x表示处理前缀i-1时到达的状态)
如果可以,那么len+1;否则就从father这颗树向上走,如果可以增加,那么长度等于x->MAX+1,x=x->son[B[i]],否则如果最终不可以,那么就到了根节点,长度为0。
区别一下:
子串:必须要连续
子序列:顺序固定
后缀自动机的性质:
-
有一个源点,边代表在当前字符串后增加一个字符。
-
每个点代表一个 endposendpos 等价类,到达一个点的路径形成的子串必须属于此点的类。
-
点之间有父子关系,到达点 ii 的所有字符串的长度都必然大于到达 fa(i)fa(i) 的所有字符串的长度,且到达 fa(i)fa(i) 的任意一字符串必为到达 ii 的任意一字符串的后缀。
可以解决的问题:
计算某个字符串在原串中出现的次数;(在后缀节点上大标记,该子串代表的节点子树的size就是出现次数)
两个字符串的最长公共子串;
判断子串;
计算不同子串个数;
字符串第一次出现的位置;
字符串出现在某个位置之后的次数。
计算某个字符串在原串中出现的次数:
原理:把具有相同集合的状态缩成一个点,这个点内的所有状态互为后缀。
构造方法:增量构造法,考虑这个字符的加入会使之前的所有后缀增加一个字符,所以可以通过调fail树来构造。
father:如果l[p]+1=l[q],那么可以直接连father,否则就新建立一个节点。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」