[luogu3804]【模板】后缀自动机

只是扔个代码(具体还在继续学习中)..

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
bool Finish_read;
template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;}
template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x%10+'0');}
template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('\n');}
template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);}
/*================Header Template==============*/
char s[1000005];
int n,now[2000005],op[2000005],sz[2000005];
ll ans;
namespace Suffix_Automaton {
    static const int maxn=1000005;
    struct node {
        int len,lnk;
        map<char,int>nxt;
    }st[maxn<<1];
    int cnt,lst;
    inline void init() {
        cnt=lst=1;
        /*
            multiple test cases init
            for(int i=0;i<maxn<<1;i++)
                st[i].nxt.clear();
        */
    }
    inline void Append(char c) {
        int cur=++cnt,p=lst;lst=cur;
        st[cur].len=st[p].len+1;
        while(p&&!st[p].nxt.count(c))
            st[p].nxt[c]=cur,p=st[p].lnk;
        if(!p)
            st[cur].lnk=1;
        else {
            int q=st[p].nxt[c];
            if(st[p].len+1==st[q].len)
                st[cur].lnk=q;
            else {
                int clone=++cnt;
                st[clone].len=st[p].len+1;
                st[clone].nxt=st[q].nxt;
                st[clone].lnk=st[q].lnk;
                st[q].lnk=st[cur].lnk=clone;
                while(p&&st[p].nxt[c]==q)
                    st[p].nxt[c]=clone,p=st[p].lnk;
            }
        }
        sz[cur]=1;
    }
}
using namespace Suffix_Automaton;
int main() {
    init();
    scanf("%s",s+1);
    n=strlen(s+1);
    for(int i=1;i<=n;i++)
        Append(s[i]);
    for(int i=1;i<=cnt;i++)
        op[st[i].len]++;
    for(int i=1;i<=cnt;i++)
        op[i]+=op[i-1];
    for(int i=1;i<=cnt;i++)
        now[op[st[i].len]--]=i;
    for(int i=cnt;i;i--) {
        int p=now[i];
        sz[st[p].lnk]+=sz[p];
        if(sz[p]>1)
            ans=max(ans,1ll*sz[p]*st[p].len);
    }
    printf("%lld\n",ans);
}

猜你喜欢

转载自blog.csdn.net/effervescence/article/details/79725601