zoukankan      html  css  js  c++  java
  • [OI笔记]后缀自动机

    本来没打算写的,不过想想看后缀自动机的理论看了两三天了才有点懂(我太傻了)…下周期末考的话大概要去复习一下文化课感觉回来又要忘得差不多,还是开篇blog记一下好了。

    相关的资料:

    cls当年的课件:2012年noi冬令营陈立杰讲稿

    一篇不错的blog:http://www.cnblogs.com/meowww/p/6394960.html

    因为博主比较懒(菜)所以这里就大概记一些关键的东西(其实也就只复述了一遍建SAM的过程,大概在cls课件40页左右的地方)。

    用$p$表示$p=ST(T)$且$Right(p)={Lenght+1}$的点(代码里用$last$记录),对于字符串$T$的SAM,我们在后面加入一个新的字符$x$,新建$np=ST(Tx),val[np]=val[p]+1$,对$p$所有没有$x$标号的祖先$v$,令$tr[v][x]=np$,也就是连向我们新加的点。

    就这样找到第一个有$x$标号的祖先$v_p$,这里有几种情况。如果没有找到这样的$v_p$直接令$suf[np]=root$(根作为$np$的父亲),然后就可以结束了。否则令$q=tr[v_p][x]$,这时候如果$val[v_p]+1=val[q]$的话直接让$suf[np]=q$然后结束,但是如果不行的话就有点麻烦了,这时候我们要再建一个点$nq:tr[nq][*]=tr[q][*]$,然后$suf[nq]=suf[q],suf[q]=suf[np]=nq$,最后对所有$tr[v][x]==q$的祖先$v$都改成$tr[v][x]=nq$。

    最后当然不要忘记更新$last$。

    构造大概就是这样子啦。

    inline int newNode(int x)
    {
        val[++cnt]=x;return cnt;
    }
    inline void insert(int x)
    {
        int p=last,np=newNode(val[p]+1);memset(tr[np],0,sizeof tr[np]);
        while(p&&!tr[p][x])tr[p][x]=np,p=suf[p];
        if(!p)suf[np]=1;
        else
        {
            int q=tr[p][x];
            if(val[q]==val[p]+1)suf[np]=q;
            else
            {
                int nq=newNode(val[p]+1);
                memcpy(tr[nq],tr[q],sizeof tr[nq]);
                suf[nq]=suf[q];suf[np]=suf[q]=nq;
                while(p&&tr[p][x]==q)tr[p][x]=nq,p=suf[p];
            }
        }
        last=np;
    }

    写起来还是挺短的

  • 相关阅读:
    D-Power Products
    B2
    软考知识点梳理--螺旋模型
    软考知识点梳理--敏捷方法
    软考知识点梳理--瀑布模型
    软考知识点梳理--统一软件开发过程RUP
    软考知识点梳理--信息系统生命周期
    软考知识点梳理--信息资源管理
    软考知识点梳理--以太网
    软考知识点梳理--应急储备与管理储备
  • 原文地址:https://www.cnblogs.com/yoshinow2001/p/8372722.html
Copyright © 2011-2022 走看看