后缀自动机详解
作者:互联网
当想让学妹看博客时,怕旧的写的太烂被嫌弃,又怕新的看不懂……哎
一、定义:
单词的有向无环图
二、作用
从原点出发形成的所有路径即为单词的所有子串,并且通过维护endpos和endpos类,得知每个串出现的次数和出现的位置
三、构建后缀自动机
一些性质:
-
endpos :数集,一些子串他们出现的位置相同,这些位置的集合称为endpos
-
endpos类 :串集,一些子串他们出现的位置相同,这些子串的集合称为endpos类
-
fail树 :
-
树上节点的endpos是他父亲节点endpos的真子集
-
树上节点的父亲包含的子串是当前节点包含的子串的后缀
-
树上节点的endpos类中的子串长度连续
-
树上节点的endpos类中的最小长度等于他父亲节点endpos类中的最长长度+1
后缀自动机维护的东西:
-
fail树上的父亲
-
c边连向的点
-
endpos类中最长串的长度
以上是一些概念,由他的性质和用途决定,就像1+1=2一样解释不了,早出生一点也许就不这样了呢
这些概念性的东西介绍完毕之后,就要开始讲如何维护了
考虑每次新添加一个字符进后缀自动机中(新开一个节点),改变的只有未添加新字符的所有后缀,就相当于在原来的终止节点后添加一个字符,长度+1,且每个终止节点都要向他引出一个c边,而由性质我们可以知道当前终止节点的所有祖先既终止节点集,当最终跳到源点的时候就表示,旧串中没有新形成的字符串的后缀,说明没有节点会发生改变,所以新节点的父亲指向1就可以了,所那么如下代码的意义就解释完毕:
int preNode = lastNode;
int nowNode = lastNode = ++tot;
mac[nowNode].len = mac[preNode].len+1;
for(;preNode&&!mac[preNode].ch[c];preNode = mac[preNode].fa) mac[preNode].ch[c] = nowNode;
if (!preNode) mac[nowNode].fa = 1;
如果旧串中存在新形成的字符串的后缀呢?那么说明现在的preNode之前的节点会发生改变,额……待我仔细斟酌一下再下笔,毕竟要吃饭了
标签:子串,后缀,mac,详解,endpos,自动机,preNode,节点 来源: https://www.cnblogs.com/little-uu/p/14507070.html