Code:
//【模板】后缀自动机,SAM
#include<bits/stdc++.h>
#define MAXN 3000005
#define MAXL 30
using namespace std;
inline void read(int &n){
int s=0,t=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') t=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
s=(s<<3)+(s<<1)+(c^48);c=getchar();
}
n=s*t;
}
inline void put(long long n){
if(n<0){
putchar('-');n=-n;
}
if(n<10){
putchar(n+48);return;
}
put(n/10);
putchar(n%10+48);
}
struct node{
int v,nxt;
}e[MAXN*2];
int last,cnt,tot,link[MAXN],head[MAXN],t[MAXN][MAXL];
long long ans,len[MAXN],siz[MAXN];
char s[MAXN];
inline void firstwork(){
last=0;
len[0]=0;link[0]=-1;siz[0]=1;
for(register int i=1;i<=26;++i) t[0][i]=0;
}
inline int exch(char ch){
return ch-'a'+1;
}
inline void insert(char ch){
int cur=++cnt,p=last,c=exch(ch);
len[cur]=len[last]+1;siz[cur]=1;
while(p!=-1&&!t[p][c]){
t[p][c]=cur;p=link[p];
}
if(p==-1) link[cur]=0;
else{
int q=t[p][c];
if(len[p]+1==len[q]) link[cur]=q;
else{
int clone=++cnt;
len[clone]=len[p]+1;
link[clone]=link[q];
for(register int i=1;i<=26;++i) t[clone][i]=t[q][i];
while(p!=-1&&t[p][c]==q){
t[p][c]=clone;p=link[p];
}
link[cur]=link[q]=clone;
}
}
last=cnt;
}
inline void add(int u,int v){
++tot;
e[tot].v=v;
e[tot].nxt=head[u];
head[u]=tot;
}
inline void dfs(int u){
for(register int i=head[u];i;i=e[i].nxt){
int v=e[i].v;
dfs(v);siz[u]+=siz[v];
}
if(siz[u]!=1&&siz[u]*len[u]>ans) ans=siz[u]*len[u];
}
int main(){
//freopen("P3804_3.in","r",stdin);
//freopen("P3804_3.ans","w",stdout);
int len;
cin>>s;
len=strlen(s);
firstwork();
for(register int i=0;i<len;++i) insert(s[i]);
for(register int i=0;i<=cnt;++i) add(link[i],i);
dfs(0);put(ans);putchar('\n');
return 0;
}
之前是万紫千红只对了 #2,然后玄学的调了亿下就 A 了 #1,之后 #3 开始全 WA,实在是看不出来了,对 tj 看也看不出来,下载了数组发现答案只差一点点
我的代码 #3 跑出来是 784356,数据下载的是 785559,但是和 tj 一起调了亿下发现我的代码建的 SAM 节点要少得多,不知道为什么。
另外,调 #1 的时候,下载的数据是 1∗106 个字母 z,然后理所应当输出是 5∗105∗(5∗105+1),然后我的输出就很小,发现不用文件的话整个字符串的大小只有 4094,很玄学,开了文件能行,大小是 1∗106,但是建完 SAM,连完 link 边建成图之后,跑 dfs 的时候跑到接近 2∗104 就罢工了,还返回了错误值,但是提交上去却 A 了 #1,不知道为什么。(在做 Z 算法模板的时候也有这个问题,明明本地输出不对,提交上去却 AC 了)
有没有大佬解释一下。