后缀自动机 笔记
来源:互联网 发布:易语言写软件 编辑:程序博客网 时间:2024/06/08 09:26
参考了hihocoder和clj的课件,看了看hzwer的代码,懂了些东西,记一下。
后缀自动机是一棵trie树。
给出一个字符串S,对于S的一个子串s,Right(s) 代表一个集合,为s在S中所有出现的结束位置集合。
以S=”aabbabd”为例,Right(“ab”) = {3, 6},因为”ab”一共出现了2次,结束位置分别是3和6。同理Right(“a”) = {1, 2, 5}, Right(“abba”) = {5}。对于一个字符串集合,若这个集合中所有的字符串拥有相同的Right集合,那么我们可以给这个集合一个状态s, 用Substring(s)代表这个集合,这个集合也对应着一个Right(s)集合。
那么现在就存在一个s <-> Substring <-> Right集合的一一对应关系。
对于Substring(s),存在longest(s)和shortest(s)分别代表Substring(s)中的最长和最短字符串,其长度分别为l(s)与r(s)。
对于一个longest(s),我们不断地去除他的第一个字符,直到其变为shortest(s),这个过程中出现的l(s)- r(s) + 1个字符串必然都属于Substring(s)。
若我们将shortest(s)的第一个字符删去(此时当然是假定shortest(s)不为空串),必然会导致状态的改变,因为此时的Right集合变大了,而s和Right(s),Substring(s)一一对应。
具体可以参照下图。
我们用fa(s)来代表从s进行的一次跳转到达的新状态。
若把状态按fa来建图,显然可以得到一个树形结构,我们称之为parent树。
对于这棵树存在以下性质:
1.
2.
定义ST(T)为从空串状态走了字符串T到达的状态,trans[p][c]代表从p状态添加新的字符c能够到达的状态。
若干个状态作为点,构成了后缀自动机,这个后缀自动机借由trans组成了trie树,而这个trie树上的部分节点又类似AC自动机的fail那样构成了parent树。
构造方法CLJ课件已经给出了,这里挂上代码并标以注释。
namespace SAM{ static const int maxnode = 2e6+10;//至少开两倍 static const int maxn = 26; int p, q, np, nq; int cnt, ST_T; int trans[maxnode][maxn], l[maxnode], fa[maxnode]; int newnode() { int x = ++cnt; memset(trans[x], 0, sizeof trans[x]); fa[x] = 0; l[x] = 0; return cnt; } void init() { cnt = 0; ST_T = newnode(); } void add(int c) { //令当前串为T,新加的字符为x。 p = ST_T; np = ST_T = newnode(); l[np] = l[p] + 1;//令p = ST(T),新建np = ST(Tx) while(!trans[p][c]&&p) trans[p][c] = np, p = fa[p];//对于p的所有没有标号c的边的祖先v,trans[v][c] = np。 if(!p) fa[np] = 1; //找到p的第一个祖先vp,他有标号c的边,如果没有这样的vp,那么fa[p]=root,结束该阶段。 else { q = trans[p][c];//令q=trans[vp][c] if(l[p] + 1 == l[q]) fa[np] = q;//若l[q] = l[vp] + 1,令fa[np] = q,结束该阶段。 else { nq = newnode(); l[nq] = l[p] + 1;//否则建立新节点nq memcpy(trans[nq],trans[q],sizeof(trans[q]));//trans(nq, *) = trans(q, *) fa[nq] = fa[q]; fa[np] = fa[q] = nq; while(trans[p][c] == q) trans[p][c] = nq, p = fa[p];//对于所有的trans(v, c) == q的p的祖先v, trans(v, c)改为nq。 } } } void build(char *str) { int len = strlen(str); for(int i = 0; i < len; i++) add(str[i]-'a'); }};
- 后缀自动机学习笔记
- 后缀自动机 笔记
- 后缀自动机学习笔记
- 后缀自动机学习笔记3
- [Notes] 后缀自动机学习笔记
- [学习笔记] 后缀自动机学习笔记
- 后缀自动机(SAM)学习笔记
- SAM 后缀自动机——学习笔记
- 【字符串数据结构后缀系列Part2】后缀自动机学习笔记
- 后缀自动机
- 后缀自动机
- 后缀自动机
- 后缀自动机
- 后缀自动机)
- 后缀自动机
- 后缀自动机
- 后缀自动机
- 后缀自动机
- 学生成绩转换
- spring
- PTA 排座位(25 分)
- 「算法精解_C语言描述」 链表_双向链表的实现与分析
- JZOJ 5459. 【NOIP2017提高A组冲刺11.7】密室
- 后缀自动机 笔记
- 从multiprocessing源码理解其对SIGINT信号的屏蔽
- NOIP模拟 图【最小生成树】
- 文章标题
- 洛谷 NOIP 模拟 DAY2
- 会动的圆
- navigator对象
- NYOJ 过河问题
- 入阵曲+将军令