后缀自动机SAM

附:本文参考(后缀自动机学习总结)[http://blog.sina.com.cn/s/blog_70811e1a01014dkz.html]

先感性认知一下
这是一个建好的 字符串ACADD的SAM 示意图
kAv36O.jpg

每一个节点要维护的东西如下

  • Sigma
    常数,表示字符的种类数,比如维护小写字母字符串时为26
  • son[1 ~ Sigma](上图实线箭头) 子节点的指针
  • link(上图的虚线箭头)
    上一个可以接收后缀的结点
    注意link不是该点的父结点!(因为一个点有可能是多个点的儿子)
  • len
    从根结点走到当前点,最多需要多少步

SAM性质:

  • 从root到任意结点p的每条路径上的字符组成的字符串,都是当前串t的子串.
  • 因为满足性质一,所以如果当前结点p是可以接收新后缀的结点(被link指向),那么从root到任意结点p的每条路径上的字符组成的字符串,都是必定是当前串t的后缀.
  • 如果结点p可以接收新的后缀,那么p的link指向的结点也可以接收后缀,反过来就不行.

可以推出

  • 按照字典序遍历SAM可得到所有子串(是去重的 当然也可以通过记录节点的size来维护)
  • 从最后加入的一个点(肯定是原字符串的末尾节点嘛)向前找link 找到的就是所有的后缀结尾

然后就是建图辽
由于每一步都是一样的
在这里直接从一半开始建

现在要插入一个新的点np

  • STEP1
    对于一个已经建了一半的SAM 找到它最后一个被插入的点p(因为这个点必然可接受后缀
    然后用p向前跳link 直到被跳到的点满足有 np表示的字符的儿子指针

那如果最后跳到了一个 有 np表示字符的 儿子指针 的p 那可怎么办?
(这样的话 那个儿子表示的意思就重复了啊!

  • STEP2
    设那个已经有的儿子为q 如果q.len是p.len+1
    说明这个点表示的字符串可以代替p表示的字符串
    把p的link连到q上 (不想直接去重 把q的size++就好了
    (其实这个判定只是一个省节点的优化,直接复制不会错)

但如果q.len > p.len + 1的话
就不能代替 而要新建一个点nq
参考博客中给出理由(这里的step就是上文的len)

这和上一种情况一样,也面临着q点是否可以当成x结点的问题.在上一种情况的描述中,我们可以知道, step[q]=step[p]+1可以保证q原本是从p的路径上来的,而且p和q之间不会夹杂其它字符,所以可以直接把q结点当成x结点.那么反过来, step[q]>step[p]+1,就说明p和q之间有可能会夹杂其它字符,这就不能保证把q当成x结点以后,到q的路径都是tx的后缀了,于是我们不能采取和前一种情况一样的做法.但是,我们可以模仿前一种情况的做法.

然后接下来要做的事情相当麻烦。。
要复制到nq上的信息:son; link(nq.link = p);
另外的信息:nq.len = p.len + 1; nq.size = 1; q.link = nq; np.link = nq;
最后把p按link向上跳,把所有的son[np] = q的点的儿子指针都指到nq上

几道题
[AHOI2013]差异
把SAM当图看 题里那个式子就是路径长度嘛。。

Standing Out from the Herd
广义SAM
其实就是加上这个

    if(sam[last].ch[c] && sam[last].len + 1 == sam[sam[last].ch[c]].len){
        last = sam[last].ch[c];
        sam[last].flag = -1;
        return ;
    }

[NOI2016]优秀的拆分
后缀数组的题 正向维护一个SA 逆向维护一个SA
题解

[NOI2015]品酒大会
感觉像SAM裸题
那个inf设得我丧心病狂
也是把SAM当图看
建完sam后DP一下最大值最小值
ans必然是maxmax或minmin

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值