rt,按照oiwiki的代码写的,样例输出 9,看了两小时也没看出来问题,求大佬帮忙调调 orz。
// Problem: P6139 【模板】广义后缀自动机(广义 SAM)
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P6139
// Memory Limit: 500 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#define ll long long
using namespace std;
string s;
int tot=0;
struct que{
int last,now;
};
queue<que> q;
struct Node{
int fa,len,nex[27];
}a[2000001];
void inserttrie(string t){
int len=t.length(),p=0;
for(int i=0;i<len;i++){
int num=t[i]-'a'+1;
if(!a[p].nex[num]) a[p].nex[num]=++tot;
else break;
p=a[p].nex[num];
}
}
int insertsam(int last,int num){
int p=last,np=a[last].nex[num];
if(a[np].len) return np;
a[np].len=a[p].len+1;p=a[p].fa;
for(;p!=-1 && !a[p].nex[num];p=a[p].fa) a[p].nex[num]=np;
if(p==-1) a[np].fa=0;
else{
int q=a[p].nex[num];
if(a[q].len==a[p].len+1) a[np].fa=q;
else{
int clone=++tot;a[clone].fa=a[q].fa;
a[clone].len=a[p].len+1;
for(int i=1;i<=26;i++){
if(a[a[q].nex[i]].len)a[clone].nex[i]=a[q].nex[i];
else a[clone].nex[i]=0;
}
for(;p!=-1 && a[p].nex[num]==q;p=a[p].fa) a[p].nex[num]=clone;
a[q].fa=a[np].fa=clone;
}
}
return np;
}
void build(){
for(int i=1;i<=26;i++) if(a[0].nex[i]) q.push((que){0,i});
while(!q.empty()){
int num=q.front().now,last=q.front().last;q.pop();
int cur=insertsam(last,num);
for(int i=1;i<=26;i++)if(a[cur].nex[i])q.push((que){cur,i});
}
}
int main(){
int n;
cin>>n;
a[0].fa=-1;
for(int i=1;i<=n;i++){
cin>>s;
inserttrie(s);
}
build();
ll ans=0;
for(int i=1;i<=tot;i++){
ans+=(ll)(a[i].len-a[a[i].fa].len);
}
cout<<ans;
}