[复习资料]关于自动机

关于自动机

总结一下自动机。

关于AC自动机(ACAM)

以下是基础:

  • 在具体实现中 ACAM 存了两个东西 fail[] son[][] ,其中 fail[] 表示的是某个结点表示的字符串的最长的满足在 Trie 树上面出现过的后缀对应的结点(后缀链接), tr[][] 存的是某个结点向后添加字符可以到达的结点( Trie 树上面的所有边)。

以下是基础操作:

  • 一个字符串在 ACAM 上面匹配(前面删字符,后面加字符), ACAM 失配后自动跳跃改造。(利用后缀链接)
  • 在 ACAM 上面 dp ,矩阵快速幂优化转移。(讲的所有自动机都可以实现这一操作)
  • 找 Trie 树上面有哪些字符串是某个字符串的子串。(有后缀链接的自动机都可以实现这一操作)

关于后缀自动机(SAM)

用一个字符串的最后一个字符出现的位置( endpos )代表这个字符串出现的位置。

lcp 表示最长公共后缀, lcs 表示最长公共前缀。

以下是基础:

  • 在具体实现中 SAM 存了三个东西 len[] pa[] son[][] ,其中 len[] 表示的是某个结点存的最长字符串的长度, pa[] 存的是某个结点的后缀链接, son[][] 存的是某个结点向后添加字符可以到达的结点。
  • SAM 上面每个结点存的字符串本质不同。
  • SAM 上面某个结点 x 存的是长度连续的若干字符串(在具体实现中长度是 len[pa[x]]+1len[x] ),并且结点里面的所有字符串都是其中最长字符串的一个后缀,并且同一个结点里面存的所有字符串出现过的位置集合都相同。
  • pa[x] 存的每个字符串都是 x 存的每个字符串的后缀,所以跳 pa[x] 就是跳后缀。
  • 通过 pa[] 这个数组可以建出 parent 树:
    • 在 parent 树中一个点中的字符串的所有出现位置是它的子树中所有非复制结点的加入位置的并集。
    • 反串的 parent 树就是后缀树。(方便查询子串 lcp )

以下是基础操作:

  • 倍增找某个子串在 SAM 上对应位置。
  • 一个字符串在 SAM 上面匹配(前面删字符,后面加字符), SAM 失配后自动跳跃改造。(利用后缀链接)
  • 线段树合并或 dsu on tree 维护或查询 endpos 集合,在 endpos 集合上面做文章。
  • LCT 动态维护所有结点的最晚出现位置。(在 parent 树上面搞, access 操作中的虚实边切换,类似颜色段均摊)
  • 找形如 “AA” 的字符串,枚举 “A” 的长度 \(l\) ,然后每隔 \(l\) 画一刀,通过查询相邻两刀的 lcp 和 lcs 找到所有 “AA” 的字符串。

关于回文自动机(PAM)

以下是基础:

  • 在具体实现中 PAM 存了三个东西 len[] fail[] son[][] ,其中 len[] 表示的是某个结点对应回文串的长度, fail[] 存的是某个结点的后缀链接, son[][] 存的是某个结点向左右添加字符可以到达的结点。
  • PAM 维护了两棵类似 Trie 树一样的东西,分别存储长度为奇数的回文串与长度为偶数的回文串,方便起见规定奇根字符串长度为 -1 ,偶根字符串长度为 0 ,每次向下走表示的是向左右两边添加字符。

以下是基础操作( PAM 有些地方和 SAM 很像):

  • 一个字符串在 PAM 上面匹配(前面删字符,后面加字符), PAM 失配后自动跳跃改造。(利用后缀链接)
  • 线段树合并或 dsu on tree 维护或查询 endpos 集合,在 endpos 集合上面做文章。
  • LCT 动态维护所有结点的最晚出现位置。
  • 回文划分类题目,一个回文串的回文后缀只能被划分成 \(\log_2n\) 个等差数列。
  • 前后添加字符同时动态维护。

关于子序列自动机

以下是基础:

  • 在具体实现中子序列自动机只存了每个点的出边,子序列自动机利用的思想是贪心来减少连边的数量。

以下是基础操作:

  • 一个字符串在子序列自动机上面匹配。
  • 边数过多的时候用 vector 加二分或者主席树来假装存下所有边。
posted @ 2023-05-14 10:24  xiaolilsq  阅读(79)  评论(0编辑  收藏  举报