rt
50pts,用的 AC 自动机,大概是给 fail 树儿子排序时出了点正确性问题。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#define N 510001
#define LL long long
using namespace std;
int n; char s[N];
vector<int> e[N];
int tot,ch[N][26],fail[N],vis[N],siz[N],val[N];
void ins(char *s,int len) {
int p=0;
for (int i=0;i<len;i++) {
if (!ch[p][s[i]-'a']) ch[p][s[i]-'a']=++tot;
p=ch[p][s[i]-'a'];
}
vis[p]=1;
}
void getfail() {
queue<int> q;
for (int i=0;i<26;i++)
if (ch[0][i]) q.push(ch[0][i]);
while (!q.empty()) {
int x=q.front(); q.pop();
for (int i=0;i<26;i++)
if (ch[x][i]) fail[ch[x][i]]=ch[fail[x]][i],q.push(ch[x][i]);
else ch[x][i]=ch[fail[x]][i];
}
for (int i=1;i<=tot;i++) e[fail[i]].push_back(i);
}
int num; LL ans;
void dfs0(int u) {
val[u]=siz[u]=vis[u];
for (int v:e[u]) {
dfs0(v);
siz[u]+=siz[v];
if (!vis[u]) {
if (vis[v]) val[u]++;
else val[u]+=val[v];
}
}
}
void dfs(int u,int las) {
if (vis[u]) ++num,ans+=num-las,las=num;
for (int v:e[u]) dfs(v,las);
}
int main() {
scanf("%d",&n);
for (int i=1;i<=n;i++) {
cin>>s; int len=strlen(s);
ins(s,len);
}
getfail(); dfs0(0);
for (int i=0;i<=tot;i++) sort(e[i].begin(),e[i].end(),[](int tmp1,int tmp2) { return siz[tmp1]^siz[tmp2]?siz[tmp1]<siz[tmp2]:val[tmp1]>val[tmp2]; });
dfs(0,0);
printf("%lld\n",ans);
return 0;
}