1. 程式人生 > >【模板】字尾自動機

【模板】字尾自動機

模板題,這裡放一下程式碼:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 1000050
#define ll long long
char s[N];
ll ans = 0;
struct SAM
{
    int tot,las;
    int siz[2*N];
    SAM(){tot=las=1;}
    struct Poi
    {
        int pre,trs[28],len;
    }p[2*N];
    
struct EG { int to,nxt; }e[2*N]; int hed[2*N],cnt; void ae(int f,int t) { e[++cnt].to = t; e[cnt].nxt = hed[f]; hed[f] = cnt; } void insert(int c) { int np,nq,lp,lq; np=++tot; siz[np]=1; p[np].len=p[las].len+1
; for(lp=las;lp&&!p[lp].trs[c];lp=p[lp].pre) p[lp].trs[c]=np; if(!lp)p[np].pre=1; else { lq = p[lp].trs[c]; if(p[lq].len==p[lp].len+1)p[np].pre=lq; else { nq = ++tot; p[nq]
=p[lq]; p[nq].len=p[lp].len+1; p[lq].pre=p[np].pre=nq; while(p[lp].trs[c]==lq) { p[lp].trs[c]=nq; lp=p[lp].pre; } } } las=np; } void build() { for(int i=2;i<=tot;i++) ae(p[i].pre,i); } void dfs(int u) { for(int j=hed[u];j;j=e[j].nxt)dfs(e[j].to),siz[u]+=siz[e[j].to]; if(siz[u]!=1)ans=max(1ll*siz[u]*p[u].len,ans); } }sam; int len; int main() { scanf("%s",s+1); len = strlen(s+1); for(int i=1;i<=len;i++) sam.insert(s[i]-'a'+1); sam.build(); sam.dfs(1); printf("%lld\n",ans); return 0; }