[Notes][模板] 记(瞎写) · 后缀自动机

来源:互联网 发布:乐高ev3大象编程 编辑:程序博客网 时间:2024/06/07 14:28

SAM


后缀自动机,就是一个能接受一个字符串所有后缀的自动机,本质是字典树。

考虑一个能接收一个字符串所有后缀的数据结构,显然字典树可以——只要把所有后缀加到字典树中,但是这样节点的个数是O(N2)的,接受不了,还有就是后缀树,但是后缀树的构造方法极其麻烦。这个时候后缀自动机就是很好的选择(事实上它也具备字典树和后缀树的性质)

构造


后缀自动机的构造不能说简单但是好记
可以看有具体证明的clj的课件:https://wenku.baidu.com/view/fa02d3fff111f18582d05a81.html
网上大佬的介绍(比较简单易懂):http://blog.sina.com.cn/s/blog_70811e1a01014dkz.html
还有一篇很具体的:http://e-maxx.ru/algo/suffix_automata

应用


个人把后缀自动机的应用分为两种:

  • 1.利用其本质是字典树以及它的fail指针
    因为本质是字典树切具有fail指针,那么就可以进行字符串匹配

    • 一个串u在另一个串v中的出现位置——对v建出后缀自动机,u在后缀自动机上跑,匹配不了就沿着fail指针继续匹配,找到终止位置x,x的right集合就是u在v中出现的位置的集合。
    • 两个串的最长公共子串——一个串在在另一个串的后缀自动机上跑,能匹配则答案加一,不能就沿fail指针匹配,然后把答案设为当前节点的len。具体应用:http://blog.csdn.net/coldef/article/details/75127222(calc函数)
    • 多个串的最长公共子串——对其中一个串建出后缀自动机,把另外所有串都放到上面跑一边,每个串求出在每个节点上的最长公共子串,每个节点取所有串在这个节点上答案的最小值,然后后缀自动机上每个节点的最大值就是答案,具体应用:SPOJ1812,BZOJ2946
    • 最小表示法——建出后缀自动机,每次往最小的儿子跑
      BZOJ2882 http://blog.csdn.net/coldef/article/details/54790695
    • k小子串——建出后缀自动机,然后每个节点类似“26分”地跑:
      bzoj3998 http://blog.csdn.net/coldef/article/details/54783495
      ……
  • 2.利用它fail指针构成的parent树

    • 主要是用来DP
      还有一个性质,一个串的后缀自动机的parent树是反串的后缀树
      根据这个性质,就可以求两个后缀的LCP(后缀树上的LCA)
      bzoj3238 http://blog.csdn.net/coldef/article/details/54798928
  • 3.还有就是可以用来构造后缀树组或后缀树(上面有说),然而我不会构造后缀树组…