后缀自动机
-
后缀自动机 可以识别所有子串
-
求本质不同的子串 len[i]−link[len[i]]len[i]-link[len[i]]len[i]−link[len[i]]
``
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e6+10;
typedef long long ll;
ll ans=0;
ll dp[MAXN<<1];
struct SAM{
int sz,last;
int link[MAXN<<1],trans[MAXN<<1][26],len[MAXN<<1];
SAM(){
sz=last=0;len[0]=0;link[0]=-1;
}
void init(){
sz=last=0;len[0]=0;link[0]=-1;
memset(trans,0,sizeof trans);
}
void extend(int id){
int cur=++sz,p;
len[cur]=len[last]+1;dp[cur]=1;
for(p=last;p!=-1 && !trans[p][id];p=link[p]) trans[p][id]=cur;
if(p==-1) link[cur]=0;
else {
int q=trans[p][id];
if(len[p]+1==len[q]) link[cur]=q; ////1.
else{
int clone=++sz;
len[clone]=len[p]+1;
link[clone]=link[q];
memcpy(trans[clone],trans[q],26*sizeof(int));//字符数
for(;p!=-1 && trans[p][id]== q ;p=link[p]) trans[p][id]=clone;
link[q]=link[cur]=clone;//
}
}
last=cur;
}
} T;
int n;
string str;
vector<int> e[MAXN<<1];
void dfs(int u){
// dp[u]=1;
for(int i=0;i<e[u].size();i++){
int v=e[u][i];
dfs(v);
dp[u]+=dp[v];
}
// if(dp[u]>1) ans=max(ans,1ll*(dp[u])*T.len[u]);
}
int main(){
cin>>str;n=str.size();
for(int i=0;i<n;i++) T.extend(str[i]-'a');
for(int i=1;i<=T.sz;i++){
e[T.link[i]].push_back(i);
}
ans=0;
dfs(0);
// for()
for(int i=1;i<=T.sz;i++){
if(dp[i]>1) ans=max(ans,1ll*(dp[i])*T.len[i]);
}
cout<<ans<<endl;
return 0;
}