zoukankan      html  css  js  c++  java
  • 【模板】后缀自动机 (SAM)

    P3804 【模板】后缀自动机 (SAM)

    参考: 不同子串个数

    d[i]来表示该状态点是否为终止点,最后利用每个点的后缀链接形成一棵树,每个点所表示的最长字符串都是其子树中各节点的最长公共后缀。

    // Created by CAD
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e6+5;
    struct state{
        int len,link;
        vector<int> Next;
        state(){Next.resize(26);}
    }st[maxn<<1];
    int siz=0,last=0;
    void init(){
        st[0].len=0;
        st[0].link=-1;
    }
    int d[maxn<<1];
    void extend(int c){
        int cur=++siz;
        d[cur]=1;
        st[cur].len=st[last].len+1;
        int p=last;
        while(~p&&!st[p].Next[c]){
            st[p].Next[c]=cur;
            p=st[p].link;
        }
        if(p==-1) st[cur].link=0;
        else{
            int q=st[p].Next[c];
            if(st[p].len+1==st[q].len) st[cur].link=q;
            else{
                int clone=++siz;
                st[clone].len=st[p].len+1;
                st[clone].Next=st[q].Next;
                st[clone].link=st[q].link;
                while(~p && st[p].Next[c]==q){
                    st[p].Next[c]=clone;
                    p=st[p].link;
                }
                st[q].link=st[cur].link=clone;
            }
        }
        last=cur;
    }
    int ans;
    vector<int> g[maxn<<1];
    void dfs(int u){
        for(auto i:g[u]){
            dfs(i);
            d[u]+=d[i];
        }
        if(d[u]!=1) ans=max(ans,d[u]*st[u].len);
    }
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0);
        init();
        string s;cin>>s;
        for(auto i:s)
            extend(i-'a');
        for(int i=1;i<=siz;++i)
            g[st[i].link].push_back(i);
        dfs(0);
        cout<<ans<<endl;
        return 0;
    }
    
  • 相关阅读:
    RedHat的定制安装
    Linux系统概述
    嵌入式学习方法
    mysql联合查询
    mysql之count
    memcached安装
    css书写规则
    nginx的fastcgi_param参数详解
    array_2.array_rand
    array_1.array_map
  • 原文地址:https://www.cnblogs.com/CADCADCAD/p/13380260.html
Copyright © 2011-2022 走看看