「笔记」后缀三姐妹
写在前面
这里曾经有一篇很长的文章,由于太粪了被削除了。以下是全新的重置版本。
为什么下面有四个?四大天王有五个不也是常识吗
「笔记」后缀数组
字符串 \(S\) 的后缀数组定义为两个数组 \(sa,rk\)。
\(sa\) 储存 \(S\) 的所有后缀 按字典序排序后的起始下标,满足 \(S[sa_{i-1}:n]<S[sa_i:n]\)。
\(rk\) 储存 \(S\) 的所有后缀的排名。
结合后缀的最长公共前缀,后缀数组可以用来处理许多复杂度字符串问题。
「笔记」后缀树
对于一个字符串 \(S\),它的后缀树是由其所有后缀 \(S[i:n]\,(1\le i\le n)\) 组成的,经过信息压缩后的 Trie 树。
后缀数组可以看作由后缀树的所有叶结点按字典序排列得到的数组。
「笔记」后缀自动机
字符串 \(S\) 的后缀自动机 (suffix automaton, SAM) 是一个可以且尽可以接受 \(S\) 所有后缀的 最小的 DFA。
更形式化的定义:
- 字符串 \(S\) 的 SAM 是一张 DAWG(有向单词无环图)。节点被称作 状态,边被称作状态间的 转移。
- 存在一个起始节点,称作 起始状态。其它节点均可从起始节点出发到达。
- 每个 转移 都标有一些字母。从一个节点出发的所有转移均 不同。
- 存在数个 终止状态。若从 \(t_0\) 出发,最终转移到一个终止状态,路径上所有转移连接起来一定是 \(S\) 的一个后缀。\(S\) 的每个后缀均可用一条 从起始节点到某个终止状态 的路径构成。
- 在所有满足上述条件的 DFA 中,SAM 的节点数是最少的。
SAM 并不是一个典型的 DFA,在 DAWG 基础上,除 \(t_0\) 外的每个状态都被添加了一条 后缀链接。所有后缀链接组成了树状结构,这棵树被称为 parent 树。
字符串 \(S\) 的 SAM 能包含 \(S\) 所有子串的信息。
SAM 将这些信息以高度压缩的形式储存,对于一个长度为 \(n\) 的字符串,它的 SAM 空间复杂度仅为 \(O(n)\),构建 SAM 的时间复杂度也仅为 \(O(n)\)。
「笔记」广义后缀自动机
广义 SAM 是一种用于维护 Trie 的子串信息的 SAM 的简单变体。
将多个模式串插入到 Trie 后,即可使用广义 SAM 维护多模式串的信息。这是广义 SAM 最广泛的应用之一,本文的重点也在于此。其基本思想是将多串的信息进行压缩,使得 SAM 在仍满足节点数最少的同时 包含所有子串的信息。此时 SAM 中的一个状态可能同时代表多个串中相应的子串。