我终于会后缀自动机啦!
讲义什么的网上多了去了
事实上照着陈立杰老师的营员课件就能学
顺便把他的指针代码改成了数组:
//luogu 3804
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define MAXN 1000010
#define MAXM 2000010
#define MAX_SIG 26
#define lint long long
using namespace std;
struct SAM{
int fa,ch[MAX_SIG],maxn;
SAM(int _maxn=0)
{
maxn=_maxn;
memset(ch,0,sizeof(ch));
fa=0;
}
}t[MAXN<<1];
struct edges{
int to,pre;
}e[MAXM];
int etop,h[MAXN<<1],sz[MAXN<<1];
inline int add_edge(int u,int v)
{
etop++;
e[etop].to=v;
e[etop].pre=h[u];
h[u]=etop;
return 0;
}
int rt,last,top;
inline int new_sam_node(int _v=0)
{
t[++top].maxn=_v;return top;
}
inline int extend(int w)
{
int p=last,np=new_sam_node(t[p].maxn+1);
while(p&&!t[p].ch[w]) t[p].ch[w]=np,p=t[p].fa;
if(!p) t[np].fa=rt;
else{
int q=t[p].ch[w];
if(t[p].maxn+1==t[q].maxn) t[np].fa=q;
else{
int nq=new_sam_node(t[p].maxn+1);
for(int i=0;i<MAX_SIG;i++)
t[nq].ch[i]=t[q].ch[i];
t[nq].fa=t[q].fa;
t[q].fa=t[np].fa=nq;
while(p&&t[p].ch[w]==q)
t[p].ch[w]=nq,p=t[p].fa;
}
}
sz[np]=1;last=np;return 0;
}
lint ans=0;
inline int dfs(int x)
{
for(int i=h[x];i;i=e[i].pre)
sz[x]+=dfs(e[i].to);
if(sz[x]>1) ans=max(ans,(lint)sz[x]*t[x].maxn);
return sz[x];
}
inline int toi(char ch)
{
return ch-'a';
}
char s[MAXN];
int main()
{
top=0;rt=last=new_sam_node();
scanf("%s",s+1);int n=strlen(s+1);
for(int i=1;i<=n;i++) extend(toi(s[i]));
for(int i=1;i<=top;i++) add_edge(t[i].fa,i);
dfs(rt);printf("%lld\n",ans);return 0;
}