zoukankan      html  css  js  c++  java
  • 模板 后缀自动机

    后缀自动机不是Trie树上的,蒟蒻的我才知道。

    那个树叫parent。

    代码(增量构造):

    namespace SAM{
        sant s[3000000];
        int siz;
        int fin;
        lnt ans;
        void Insert(int c)
        {
            int nwp,lsp,nwq,lsq;
            nwp=++siz;
            s[nwp].len=s[fin].len+1;
            for(lsp=fin;lsp&&(!s[lsp].tranc[c]);lsp=s[lsp].pre)
                s[lsp].tranc[c]=nwp;
            if(!s[lsp].tranc[c])
                s[lsp].tranc[c]=nwp;
            else{
                lsq=s[lsp].tranc[c];
                if(s[lsq].len==s[lsp].len+1)
                    s[nwp].pre=lsq;
                else{
                    nwq=++siz;
                    s[nwq]=s[lsq];
                    s[lsq].pre=s[nwp].pre=nwq;
                    s[nwq].len=s[lsp].len+1;
                    while(s[lsp].tranc[c]==lsq)
                    {
                        s[lsp].tranc[c]=nwq;
                        lsp=s[lsp].pre;
                    }
                }
            }
            fin=nwp;
            return ;
        }
    };

    有些算法是构建在parent树上的(类似trie图中的fail树)。

    广义后缀自动机:

     1 void Insert(int c)
     2 {
     3     int nwp,lsp,nwq,lsq;bool flag(false);
     4     if(s[fin].tranc[c]&&s[s[fin].tranc[c]].len==s[fin].len+1)
     5     {
     6         nwp=s[fin].tranc[c];
     7         return ;
     8     }//特判1
     9     nwp=++siz;
    10     s[nwp].len=s[fin].len+1;
    11     for(lsp=fin;lsp&&!s[lsp].tranc[c];lsp=s[lsp].pre)s[lsp].tranc[c]=nwp;
    12     if(!lsp)s[lsp].pre=1;
    13     else{
    14         lsq=s[lsp].tranc[c];
    15         if(lsq].len==s[lsp].len+1)s[nwp].pre=lsq;
    16         else{
    17             if(s[nwp].len==s[lsp].len+1)flag=true;
    18             nwq=++siz;
    19             s[nwq]=s[lsq];
    20             s[nwq].len=s[lsp].len+1;
    21             s[nwp].pre=s[lsq].pre=nwq;
    22             while(s[lsp].tranc[c]==lsq)
    23             {
    24                 s[lsp].tranc[c]=nwq;
    25                 lsp=s[lsp].pre;
    26             }
    27         }
    28     }
    29     if(flag)fin=nwq;//特判2
    30     else fin=nwp;
    31     return ;
    32 }
  • 相关阅读:
    C++开发系列-友元函数 友元类
    C++开发系列-C语言的malloc与C++的new分配空间
    C++开发系列-内联函数
    iOS开发系列-Foundation与CoreFoundation内存管理
    C开发系列-字符串
    C开发系列-数组
    列表 元组 字典
    神奇的print
    while 语句的逻辑
    <Web Crawler><Java><thread-safe queue>
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10013968.html
Copyright © 2011-2022 走看看