直接搞个反串,然后伪广义SAM(打标记)不行马?
#include<bits/stdc++.h>
using namespace std;using ll=long long;
int rd(int x=0,char c=getchar()){int f=1;while(!isdigit(c))f=(c^'-'?1:-1),c=getchar();while(isdigit(c))x=x*10+(c^48),c=getchar();return f*x;}
const int N=1.2e6+5;
struct dat{int fa,len,nxt[27];}t[N];
int n;
int lst,T,f[N],g[N];
char s[N];
void add(int c,int op){
int p=lst,k;k=lst=++T;
if(~op)f[k]|=(1<<op);
if(op==0)g[k]++;
t[k].len=t[p].len+1;
while(~p&&!t[p].nxt[c])t[p].nxt[c]=k,p=t[p].fa;
if(!~p)return;
int q=t[p].nxt[c];
if(t[q].len==t[p].len+1){t[k].fa=q;return;}
int cpy=++T;t[cpy]=t[q];
t[cpy].len=t[p].len+1;
while(~p&&t[p].nxt[c]==q)t[p].nxt[c]=cpy,p=t[p].fa;
t[q].fa=t[k].fa=cpy;
}
ll ans;
vector<int> E[N];
void dfs(int u){
for(int v:E[u])dfs(v),f[u]|=f[v],g[u]+=g[v];
if(f[u]==3)ans=max(ans,(ll)t[u].len*g[u]);
}
int main(){
t[0].fa=-1;
scanf("%s",s+1);
n=strlen(s+1);
for(int i=1;i<=n;i++)add(s[i],0);
add(26,-1);
for(int i=n;i;i--)add(s[i],1);
for(int i=1;i<=T;i++)E[t[i].fa].push_back(i);
dfs(0);
printf("%lld",ans);
return 0;
}