莫欺少年穷,修魔之旅在这开始—>算法提高课题解
思路:
1. 统计一个单词在所有单词中出现的次数 = 统计所有前缀(其后缀 = 这个单词)出现的次数
2. 队列中的数倒着来就是拓扑序列,故可以递归求解每个单词在所有单词中出现的次数
图是盗来的,第一次看就明白了,故放此给大家参考
#include<bits/stdc++.h>
using namespace std;
const int N = 1000010;
int n;
int tr[N][26],cnt[N],idx;
int ne[N];
char str[N];
int id[210];
int q[N];
void insert(int x)
{
int p=0;
for(int i=0;str[i];i++)
{
int t=str[i]-'a';
if(!tr[p][t]) tr[p][t]=++idx;
p=tr[p][t];
cnt[p]++;
}
id[x]=p;
}
void build()
{
int hh=0,tt=-1;
for(int i=0;i<26;i++)
if(tr[0][i])
q[++tt]=tr[0][i];
while(hh<=tt)
{
int t=q[hh++];
for(int i=0;i<26;i++)
{
int p=tr[t][i];
if(!p) tr[t][i]=tr[ne[t]][i];
else
{
ne[p]=tr[ne[t]][i];
q[++tt]=p;
}
}
}
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
cin>>str;
insert(i);
}
build();
for(int i=idx-1;i>=0;i--) cnt[ne[q[i]]]+=cnt[q[i]];
for(int i=0;i<n;i++) cout<<cnt[id[i]]<<endl;
return 0;
}