luogu 3804 【模板】后缀自动机

学习一波后缀自动机

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<cstring>
 7 #include<vector>
 8 #include<queue>
 9 #include<map>
10 #define rep(i,s,t) for(register int i=(s);i<=(t);++i)
11 #define dwn(i,s,t) for(register int i=(s);i>=(t);--i)
12 #define ren for(register int i=fst[x];i;i=nxt[i])
13 #define Fill(x,t) memset(x,t,sizeof(x))
14 #define ll long long
15 #define inf 2139062143
16 #define MAXN 2001000
17 using namespace std;
18 char s[MAXN];
19 int n,rt,lst,tr[MAXN][26],tot,sz[MAXN],mxlen[MAXN],rnk[MAXN],cnt[MAXN],fa[MAXN];
20 ll ans;
21 inline void extend(int c)
22 {
23     int p=lst,np=lst=++tot;mxlen[np]=mxlen[p]+1,sz[np]=1;
24     for(;p&&!tr[p][c];p=fa[p]) tr[p][c]=np;
25     if(!p) {fa[np]=rt;return ;}
26     int q=tr[p][c];if(mxlen[q]==mxlen[p]+1) {fa[np]=q;return ;}
27     int nq=++tot;mxlen[nq]=mxlen[p]+1;
28     memcpy(tr[nq],tr[q],sizeof(tr[nq]));
29     fa[nq]=fa[q],fa[np]=fa[q]=nq;
30     for(;p&&tr[p][c]==q;p=fa[p]) tr[p][c]=nq;
31 }
32 void build()
33 {
34     rep(i,1,tot) cnt[mxlen[i]]++;rep(i,1,n) cnt[i]+=cnt[i-1];
35     rep(i,1,tot) rnk[cnt[mxlen[i]]--]=i;int p;
36     dwn(i,tot,1)
37     {
38         p=rnk[i],sz[fa[p]]+=sz[p];
39         if(sz[p]>1) ans=max(ans,1LL*sz[p]*mxlen[p]);
40     }
41 }
42 int main()
43 {
44     rt=lst=tot=1;scanf("%s",s+1);n=strlen(s+1);
45     rep(i,1,n) extend(s[i]-'a');
46     build();printf("%lld\n",ans);
47 }
View Code

猜你喜欢

转载自www.cnblogs.com/yyc-jack-0920/p/10034223.html