后缀自动机板子

https://www.luogu.org/problemnew/show/P3804

CLJ神犇WC课件

https://wenku.baidu.com/view/90f22eec551810a6f4248606.html

#include<cstdio>
#include<algorithm>
#include<cstring>
#define rep(i,s,t) for(register int i=s;i<=t;++i)
#define _rep(i,s,t) for(register int i=s;i>=t;--i)
using namespace std;
const int N=4e6+11;
typedef long long ll;
struct SAM{
    int ch[N][26],las=1,cnt=1,sz[N],fa[N],l[N],c[N],pos[N];
    ll ans;
    inline void add(int c){
        int np=++cnt,p=las;las=np;l[np]=l[p]+1;
        for(;p&&!ch[p][c];p=fa[p])ch[p][c]=np;
        if(!p)fa[np]=1;
        else{
            int q=ch[p][c];
            if(l[p]+1==l[q])
                fa[np]=q;
            else{
                int nq=++cnt;l[nq]=l[p]+1;
                memcpy(ch[nq],ch[q],sizeof ch[q]);
                fa[nq]=fa[q],fa[q]=fa[np]=nq;
                for(;ch[p][c]==q;p=fa[p])ch[p][c]=nq;
            }
        }
        sz[np]=1;
    }
    inline void solve(){
        int p;
        rep(i,1,cnt)
            ++c[l[i]];
        rep(i,1,cnt)
            c[i]+=c[i-1];
        _rep(i,cnt,1)
            pos[c[l[i]]--]=i;
        _rep(i,cnt,1){
            p=pos[i],sz[fa[p]]+=sz[p];
            if(sz[p]>1)
                ans=1ll*max(ans,1ll*sz[p]*l[p]);
        }
        printf("%lld\n",ans);
    }
}sam;
char S[N];
int main(){
    gets(S+1);
    for(register int i=1;S[i];++i)    
        sam.add(S[i]-'a');
    sam.solve();
    return 0;
}
View Code

 

posted @ 2018-05-04 21:37  Stump  阅读(265)  评论(0编辑  收藏  举报