标题党,AC 自动机求调。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N=1e6+10,M=210;
int n,id,q[N],len[M],ans[M],sum[N],fail[N],tr[N][26];
int h[N],e[N],ne[N],din[N],idx;
char t[M][N];
inline void add(int a,int b){e[idx]=b;ne[idx]=h[a],h[a]=idx++;}
inline void insert(int cur)
{
scanf("%s",t[cur]+1);len[cur]=strlen(t[cur]+1);
int p=0;
for(int i=1;i<=len[cur];i++)
{
int to=t[cur][i]-'a';
if(!tr[p][to]) tr[p][to]=++id;
p=tr[p][to];
}
ans[cur]=p;
}
inline void build(int p,int fr)
{
for(int i=0;i<26;i++)
{
if(!tr[p][i]) continue;
int now=fr;
while(now&&!tr[now][i]) now=fail[now];
fail[tr[p][i]]=now=(tr[now][i]?tr[now][i]:now);
build(tr[p][i],now);
}
}
inline void solve(int cur)
{
for(int i=1,p=0;i<=len[cur];i++)
{
int to=t[cur][i]-'a';
while(p&&!tr[p][to]) p=fail[p];
if(tr[p][to]) p=tr[p][to];sum[p]++;
}
}
int main()
{
memset(h,-1,sizeof h);
scanf("%d",&n);
for(int i=1;i<=n;i++) insert(i);
for(int i=0;i<26;i++) if(tr[0][i]) build(tr[0][i],0);
for(int i=1;i<=n;i++) solve(i);
int head=0,tail=-1;
for(int i=1;i<=id;i++) if(fail[i]) add(i,fail[i]),din[fail[i]]++;
for(int i=1;i<=id;i++) if(!din[i]) q[++tail]=i;
while(head<=tail)
{
int now=q[head++];
for(int i=h[now];~i;i=ne[i])
{
sum[e[i]]+=sum[now];
din[e[i]]--;
if(!din[e[i]]) q[++tail]=e[i];
}
}
for(int i=1;i<=n;i++) printf("%d\n",sum[ans[i]]);
return 0;
}