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

    P3804 【模板】后缀自动机

    后缀自动机模板

    详情可见luogu题解板块

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    ll max(ll a,ll b){return a>b?a:b;}
    #define N 2000005
    struct Sam{
        int nxt[N][26],fa[N],len[N],siz[N];
        int n,p,q,last,ed,c[N],a[N]; char s[N];//last:自动机的末尾点
        Sam(){ed=1;}
        void init(){
            scanf("%s",s+1); n=strlen(s+1);
            for(int i=1;i<=n;++i) add(s[i]-'a');
        }
        void add(int c){
            p=last; len[last=++ed]=len[p]+1; siz[ed]=1;
            for(;p&&!nxt[p][c];p=fa[p]) nxt[p][c]=ed;
            if(!p){fa[ed]=1; return ;}//case 1
            q=nxt[p][c];
            if(len[q]==len[p]+1){fa[ed]=q; return ;}// case 2
            len[++ed]=len[p]+1;
            memcpy(nxt[ed],nxt[q],sizeof(nxt[q]));
            fa[ed]=fa[q]; fa[q]=fa[ed-1]=ed;
            for(;nxt[p][c]==q;p=fa[p]) nxt[p][c]=ed; // case 3
        }
        void calc(){
            ll ans=0;
            for(int i=1;i<=ed;++i) ++c[len[i]];
            for(int i=1;i<=ed;++i) c[i]+=c[i-1];
            for(int i=1;i<=ed;++i) a[c[len[i]]--]=i;
            for(int i=ed;i;--i){//按len的长度逆序处理(显然len[fa[x]]<len[x])
                siz[fa[a[i]]]+=siz[a[i]];
                if(siz[a[i]]>1) ans=max(ans,1ll*siz[a[i]]*len[a[i]]);
            }printf("%lld",ans);
        }
    }sam;
    int main(){sam.init(); sam.calc(); return 0;}
  • 相关阅读:
    牛客网每日一练
    牛客网每日一练
    牛客网每日一练
    linux解压命令 迎客
    japid 研究 迎客
    Linux 下载工具 wget 迎客
    Nginx 安装 迎客
    Redmine 迎客
    安装 Redis 迎客
    http状态码一览表 迎客
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/10219920.html
Copyright © 2011-2022 走看看