后缀自动机
https://www.luogu.org/blog/Kesdiael3/hou-zhui-zi-dong-ji-yang-xie
代码
#include<bits/stdc++.h>
using namespace std;
char s[2000100];
long long Ans;
int n;
struct SAM {
int mp[2000100][30],fa[2000100],ed,ccnt,len[2000100],siz[2000100];
int head[2000100],nxt[2000100],to[2000100],cnt;
inline void ins(int x,int n1){
int p=ed;
ed=++ccnt;
siz[ccnt]=1;
len[ccnt]=n1;
while(p&&!mp[p][x]){
mp[p][x]=ed;
p=fa[p];
}
if(!p){
fa[ed]=1;
return;
}
int q=mp[p][x];
if(len[p]+1==len[q]){
fa[ed]=q;
return;
}
len[++ccnt]=len[p]+1;
for(int i=1;i<=26;i++)mp[ccnt][i]=mp[q][i];
fa[ccnt]=fa[q];
fa[q]=ccnt;
fa[ed]=ccnt;
for(int i=p;mp[i][x]==q;i=fa[i])mp[i][x]=ccnt;
}
inline void add(int x,int y){nxt[++cnt]=head[x];head[x]=cnt;to[cnt]=y;}
inline void build(){for(int i=2;i<=ccnt;i++)add(fa[i],i);}
inline void dfs(int x){
for(int i=head[x];i;i=nxt[i])
dfs(to[i]),siz[x]+=siz[to[i]];
if(siz[x]!=1)Ans=max(Ans,1ll*siz[x]*len[x]);
}
};
SAM sam;
int main(){
int i,j,k;
scanf("%s",s+1);
n=strlen(s+1);
sam.ed=sam.ccnt=1;
for(i=1;i<=n;i++)sam.ins(s[i]-'a'+1,i);
sam.build();
sam.dfs(1);
printf("%lld\n",Ans);
return 0;
}