SAM

后缀自动机(SAM)

节点意义:记录一组\(r\)相同的长度连续的子串\(s[l:r]\)\(len(x)\)表示最长的一个

\(son\)指针意义:在x记录的每一个子串后面都加上\(c\)后可以得到son(x,c)中的一个连续段(本质上是一个映射关系)

son指针仅仅是单向映射关系,因此可能会有多个y指向同一个x,比如x={cd,bcd,abcd},y1={c},y2={bc,abc},那么son(y1,d)和son(y2,d)都指向x,其中y1对应着{cd},而y2对应着{bcd,abcd}

\(fa\)指针意义:\(fa(x)\)记录的子串均是\(x\)记录的子串的后缀且是\(len\)最大的一个


构建:

  • \(prv\)为基础

    • \(prv\)没有这个儿子,son(prv)=x,prv=fa(prv)
  • \(prv\)跳到根了,则令\(fa\)=根

  • 否则令\(p\)\(son(prv,c)\)

    • \(len(p)=len(prv)+1\),fa(x)=p
    • 否则新建一个\(newp\)\(p\)的复制(fa和son信息相同),并将连向\(p\)的节点改成连向newp,并令\(len(newp)=len(prv)+1\),然后fa(x)=fa(p)=newp

构建过程中唯一难理解的问题在于为什么要复制一个p,主要原因是\(son\)指针的单向对应关系

举个例子,prv={ab,aab},p={abc,aabc,eaabc,eeaabc},x={abc,aabc,daabc},直接连fa不好处理

这个时候prv对应到p中为{abc,aabc},对应到x中为{abc,aabc},发现这两个集合是一样的,所以直接提出来(即newp),得到4个集合

prv={ab,aab},newp={abc,aabc},p={eaabc,eeaabc},x={daabc}

然后son和fa指针就可以很方便地处理了


应用扩展

广义SAM:多个字符串的SAM,有离线(trie+bfs)和在线两种做法(蒟蒻知道的最好写的在线做法就是每次插入一个新的串时把prv改成1,然后加点特判避免空节点)

利用parent树将匹配/公共串一类的字符串问题转化成更直观的树上问题

利用lct的Access操作和爬parent树的相似性,去维护到根链的相关信息(区间本质不同子串个数)

posted @ 2021-07-01 15:20  oisdoaiu  阅读(287)  评论(0编辑  收藏  举报