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

#include <bits/stdc++.h>
#define inf 2333333333333333
#define N 2000010
#define p(a) putchar(a)
#define For(i,a,b) for(int i=a;i<=b;++i)
//by war
//2020.7.24
using namespace std;
long long n,ans;
char s[N];
void in(int &x){
    int y=1;char c=getchar();x=0;
    while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    x*=y;
}
void o(int x){
    if(x<0){p('-');x=-x;}
    if(x>9)o(x/10);
    p(x%10+'0');
}

struct Node{
    int tr[26];
    int len,fa;
    Node(){memset(tr,0,sizeof tr);len=fa=0;}
}a[N];

struct node{
    int n;
    node *next;
}*e[N];

struct SAM{
    int las=1,tot=1;
    long long f[N];

    void push(int x,int y){
        node *p;
        p=new node();
        p->n=y;
        if(e[x]==0)
            e[x]=p;
        else{
            p->next=e[x]->next;
            e[x]->next=p;
        }
    }

    void add(int c){
        int p=las,np=las=++tot;f[tot]=1;
        a[np].len=a[p].len+1;
        for(;p&&!a[p].tr[c];p=a[p].fa) a[p].tr[c]=np;
        if(!p) a[np].fa=1;
        else{
            int q=a[p].tr[c];
            if(a[q].len==a[p].len+1) a[np].fa=q;
            else{
                int nq=++tot;
                a[nq]=a[q];a[nq].len=a[p].len+1;
                a[q].fa=a[np].fa=nq;
                for(;p&&a[p].tr[c]==q;p=a[p].fa)a[p].tr[c]=nq;
            }
        }
    }
    void dfs(int x){
        for(node *i=e[x];i;i=i->next){
            dfs(i->n);
            f[x]+=f[i->n];
        }
        if(f[x]!=1) ans=max(ans,f[x]*a[x].len);
    }

    void deal(){
        For(i,1,n) add(s[i]-'a');
        For(i,2,tot) push(a[i].fa,i);
        dfs(1);
        o(ans);p('
');
    }

}sam;

signed main(){
    scanf("%s",s+1);
    n=(int)strlen(s+1);
    sam.deal();
    return 0;
}
原文地址:https://www.cnblogs.com/war1111/p/13372407.html