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

    后缀自动机

    并没有搞的很清楚,凭着当前的理解胡乱bb两句得了,内容存在误导,请仔细甄别。

    • endpos集合

      每个子串结尾的位置集合。

    • 本质相同

      endpos相等的子串集合

      然后这个本质不同的集合构成自动机的状态。

    • (substr(i)),状态(i)包含的子串集合

      (len(i)),状态(i)包含的最长子串

      性质:状态(i)包含的子串是最长子串长度连续的一段后缀。

    • 后缀连接((parent)边)

      状态(i)最小子串的后缀为什么不在里面呢?

      因为在别的地方出现了后缀,被分到别的状态了。

      那么当前状态对这个别的状态连边即是后缀连接。

    • 构造流程(在线增量法)

      1. 新建一个点,然后走上一个点的parent边,如果状态未对当前连边,连上。

      2. 1步骤在根结束,par边连虚根1

      3. 1步骤在(p)结束

        • 如果(p)的后面的点与(p)长度差一个,(par)指中国后面的点,这里没有产生新状态
        • 不止差一个,(p)的末尾状态掉了,再开一个状态存一下,然后把东西继承一下,然后旧状态抵回去,最后新点再更新一下信息。
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define ll long long
    using std::max;
    const int N=2e6+10;
    int head[N],to[N],Next[N],cnt;
    void add(int u,int v){to[++cnt]=v,Next[cnt]=head[u],head[u]=cnt;}
    int tot=1,las=1,ch[N][26],siz[N],par[N],len[N],n;
    ll ans;char s[N];
    void extend(int c)
    {
        int now=++tot,p=las;
        len[now]=len[las]+1,siz[now]=1;
        while(p&&!ch[p][c]) ch[p][c]=now,p=par[p];
        if(!p) par[now]=1;
        else
        {
            int x=ch[p][c];
            if(len[p]+1==len[x]) par[now]=x;
            else
            {
                int y=++tot;
                len[y]=len[p]+1,par[y]=par[x];
                memcpy(ch[y],ch[x],sizeof(ch[x]));
                while(p&&ch[p][c]==x) ch[p][c]=y,p=par[p];
                par[now]=par[x]=y;
            }
        }
        las=now;
    }
    void dfs(int now)
    {
        for(int i=head[now];i;i=Next[i])
            dfs(to[i]),siz[now]+=siz[to[i]];
        if(siz[now]>1) ans=max(ans,1ll*siz[now]*len[now]);
    }
    int main()
    {
        scanf("%s",s+1),n=strlen(s+1);
        for(int i=1;i<=n;i++) extend(s[i]-'a');
        for(int i=2;i<=tot;i++) add(par[i],i);
        dfs(1);
        printf("%lld
    ",ans);
        return 0;
    }
    

    2019.1.4

  • 相关阅读:
    bzoj 3438: 小M的作物
    bzoj 4445 [SCOI2015] 小凸想跑步
    hdu 4899 Hero meet devil
    hdu 4898 The Revenge of the Princess’ Knight
    【NOIP1999】拦截导弹
    【OpenJudge】2991:2011 题解
    【cqbzoj】1785:残缺棋盘上放车的方案数 --状压dp --输入毁一生
    【cqbzoj】:1330 Prime DP(Ahio2001 质数和分解)
    【Openjudge:Noi】7891:一元三次方程求解 c++
    【USACO FEB 2010 SILVER】吃巧克力(Chocolate Eating)
  • 原文地址:https://www.cnblogs.com/butterflydew/p/10222207.html
Copyright © 2011-2022 走看看