#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e6+10;
int read() {
int x=0,f=1;
char ch=getchar();
while(ch<48||ch>57) {
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>=48&&ch<=57) {
x=(x<<3)+(x<<1)+(ch^48);
ch=getchar();
}
return x*f;
}
struct state {
int len,link;
map<char,int> nxt;
};
char s[N];
int n,ans=0,t[N],a[N],b[N];
struct SAM {
state st[N*2];
int siz,last;
void init() {
st[0].link=-1;
siz=0;
last=0;
}
void extend(char c) {
int cur=++siz,p=last;
st[cur].len=st[last].len+1;
b[cur]=1;
while(p!=-1&&!st[p].nxt.count(c)) {
st[p].nxt[c]=cur;
p=st[p].link;
}
if(p==-1) st[cur].link=0;
else {
int q=st[p].nxt[c];
if(st[p].len+1==st[q].len) {
st[cur].link=q;
} else {
int k=++siz;
st[k].len=st[p].len+1;
st[k].nxt=st[q].nxt;
st[k].link=st[q].link;
while(p!=-1&&st[p].nxt[c]==q) {
st[p].nxt[c]=k;
p=st[p].link;
}
st[q].link=st[cur].link=k;
}
}
last=cur;
}
}Sam;
void solve() {
for(int i=1;i<=Sam.siz;i++) t[Sam.st[i].len]++;
for(int i=1;i<=Sam.siz;i++) t[i]+=t[i-1];
for(int i=1;i<=Sam.siz;i++) a[t[Sam.st[i].len]--]=i;
for(int i=Sam.siz;i;i--) {
int x=a[i];
b[Sam.st[x].link]+=b[x];
if(b[x]>1) ans=max(ans,b[x]*Sam.st[x].len);
}
}
signed main() {
cin>>(s+1);
n=strlen(s+1);
Sam.init();
for(int i=1;i<=n;i++) Sam.extend(s[i]);
solve();
printf("%lld\n",ans);
return 0;
}
标签:nxt,cur,SAM,int,len,st,link
From: https://www.cnblogs.com/Diamondan/p/17072152.html