后缀自动机算法复习回顾
发布日期:2021-06-27 15:38:09
浏览次数:2
分类:技术文章
本文共 2338 字,大约阅读时间需要 7 分钟。
讲解
本篇博文其实只是笔者个人的做法复习笔记罢了,
如果是为学习后缀自动机不小心点进来的看官们,
我推荐先看 ,名副其实。
实现
0.Structure
struct SAM{ int s[MAXC],fa; int len; SAM(){ memset(s,0,sizeof(s));fa=len=0;}}sam[MAXN<<1];
1.建立:插入点
新点 c ( c h a r ) c_{(char)} c(char) 插入末端 → l e n n p = + + c n t len_{np=++cnt} lennp=++cnt 赋为 l e n p = l a s t + 1 len_{p=last}+1 lenp=last+1
→ 往 p p p 的父亲找, p = f a p p=fa_p p=fap,沿途把无 s [ c ] s[c] s[c] 的点连向 n p np np , 然后 → ① ① ① 直到结束无 s [ c ] s[c] s[c], f a n p fa_{np} fanp 赋为 1。② ② ② 找到第一个 s [ c ] s[c] s[c] 记为 q q q →
C a s e # 1 \;\;\;\;\;\;\;\;\;\;\;\;Case\;\#1\; Case#1 l e n q = = l e n p + 1 len_q==len_p+1 lenq==lenp+1,直接把 f a n p fa_{np} fanp 赋为 q q q。C a s e # 2 \;\;\;\;\;\;\;\;\;\;\;\;Case\;\#2\; Case#2 l e n q > l e n p + 1 len_q > len_p+1 lenq>lenp+1, e n d p o s n p endpos_{np} endposnp(位置集) 不是 e n d p o s q endpos_q endposq 的子集,不能连父亲,于是把 q q q 拆了:
新建点 n q = + + c n t , s a m [ n q ] = s a m [ q ] nq=++cnt,sam[nq]=sam[q] nq=++cnt,sam[nq]=sam[q],把 q q q 先全部复制到 n q nq nq 上 → l e n n q = l e n p + 1 len_{nq}=len_p+1 lennq=lenp+1 → 把 f a q fa_{q} faq 和 f a n p fa_{np} fanp 赋为 n q nq nq → 继续往 p p p 的父亲找, p = f a p p=fa_p p=fap ,把 s [ c ] = = q s[c]==q s[c]==q 的改为连向 n q nq nq。图示:
模板:
int las = 1,cnt = 1;int f[MAXN<<1]; //extravoid addsam(int c) { int p = las; int np = (las = ++ cnt); f[np] = 1; //extra sam[np].len = sam[p].len + 1; for(;p && !sam[p].s[c];p = sam[p].fa) sam[p].s[c] = np; if(!p) sam[np].fa = 1; else { int q = sam[p].s[c]; if(sam[q].len == sam[p].len + 1) sam[np].fa = q; else { int nq = ++ cnt;sam[nq] = sam[q]; sam[nq].len = sam[p].len + 1; sam[np].fa = sam[q].fa = nq; for(;p && sam[p].s[c] == q;p = sam[p].fa) sam[p].s[c] = nq; } } return ;}
2.处理出现次数
注意到上面注释 //extra
的地方,即是出现次数的初步处理
模板:
vector g[MAXN<<1];void build_Parent_Tree() { for(int i = 2;i <= cnt;i ++) g[sam[i].fa].push_back(i);}void dfs(int x) { for(int i = 0;i < (int)g[x].size();i ++) { dfs(g[x][i]); f[x] += f[g[x][i]]; }}
3.用法
- SAM 和 Parent Tree 高度统一,SAM 上每个点存的出现次数同时也是 Parent Tree 上每一等价类中所有子串出现次数
- Parent Tree 中的父边在字符串匹配时可以当 AC 自动机中的 fail 边用
- 由于 SAM 是个 DAG ,可以进行 DAG 的各种操作,拓扑、DP、…
- ( T o b e c o n t i n u e d ) (To\;be\;continued) (Tobecontinued)
转载地址:https://blog.csdn.net/weixin_43960414/article/details/111990471 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
关注你微信了!
[***.104.42.241]2024年04月14日 22时20分18秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
【Linux】设置防火墙让外界访问服务器
2019-04-28
【webservice】通过webservice判断手机卡号类型
2019-04-28
【leetcode之旅】 数组 - 414.第三大的数
2019-04-28
【leetcode之旅】 数组 - 448.找出所有数组消失的数
2019-04-28
【leetcode之旅】 数组 - 485.最大连续1的个数
2019-04-28
【leetcode之旅】 数组 - 561.数组拆分I
2019-04-28
Android面试必问!我的移动开发春季历程,大厂内部资料
2019-04-28
Android面试送分题:来看看移动端小程序技术的前世今生!附赠课程+题库
2019-04-28
从入门到精通!已成功拿下字节、腾讯、脉脉offer,看看这篇文章吧!
2019-04-28
金九银十Android热点知识!如何快速的开发一个完整的直播app,内含福利
2019-04-28
金九银十Android热点知识!字节跳动移动架构师学习笔记,面试真题解析
2019-04-28
阿里P7亲自教你!34岁安卓开发大叔感慨,Android面试题及解析
2019-04-28
阿里P7大佬手把手教你!系统盘点Android开发者必须掌握的知识点,系列篇
2019-04-28
阿里P7大牛手把手教你!十多家大厂Android面试真题锦集干货整理,聪明人已经收藏了!
2019-04-28
阿里P7大牛整理!腾讯+字节+阿里面经真题汇总,书籍+视频+学习笔记+技能提升资源库
2019-04-28
android面试准备中高级简书!致Android高级工程师的一封信,内含福利
2019-04-29
Android面试回忆录:在字节跳动我是如何当面试官的,面试心得体会
2019-04-29