只是扔个代码(具体还在继续学习中)..
#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);
}