洛谷P3804 后缀自动机
先贴板子,留坑
#include<bits/stdc++.h> #define ll long long #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define rep(ii,a,b) for(int ii=a;ii<=b;++ii) #define per(ii,a,b) for(int ii=b;ii>=a;--ii) using namespace std;//head const int maxn=2e6+10,maxm=27+10; int casn,n,m,k; namespace sam{ int fa[maxn<<1],son[maxn<<1][maxm],len[maxn<<1]; int last,cnt,t[maxn],val[maxn],num[maxn],a[maxn]; void insert(int ch){ int pos=last,npos=++cnt; last=npos,len[npos]=len[pos]+1; for(;pos&&!son[pos][ch];pos=fa[pos]) son[pos][ch]=npos; if(!pos) fa[npos]=1; else { int q=son[pos][ch]; if(len[pos]+1==len[q]) fa[npos]=q; else { int nq=++cnt;len[nq]=len[pos]+1; memcpy(son[nq],son[q],sizeof(son[q])); fa[nq]=fa[q];fa[q]=fa[npos]=nq; for(;son[pos][ch]==q;pos=fa[pos]) son[pos][ch]=nq; } } val[npos]=1; } void makesam(char *s,int len){ last=cnt=1;rep(i,1,len) insert(s[i]-'a'); } ll getans(){ ll ans=0; rep(i,1,cnt)++num[len[i]]; rep(i,1,cnt)num[i]+=num[i-1]; rep(i,1,cnt)a[num[len[i]]--]=i; per(i,1,cnt){ int pos=a[i];val[fa[pos]]+=val[pos]; if(val[pos]>1) ans=max(ans,1ll*val[pos]*len[pos]); } return ans; } } char s[maxn]; int main(){IO; cin>>(s+1);n=strlen(s+1); sam::makesam(s,n); cout<<sam::getans()<<endl; }