Description
某人读论文,一篇论文是由许多单词组成。但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次。
InputOutput
输出N个整数,第i行的数字表示第i个单词在文章中出现了多少次。
AC自动机模板题。
#include<cstdio>
#include<cstring>
int ch[1000010][30],f[1000010],la[1000010],len[210],pl[210],que[1000010],ans[1000010];
bool b[1000010];
char s[1100010],fm[210][1000010];
void add(int p)
{
if (p)
{
ans[p]++;
add(la[p]);
}
}
int main()
{
int i,j,k,l=0,m=0,n,p,q,x,y,z,hd,tl;
scanf("%d",&n);
for (i=1;i<=n;i++)
{
scanf("%s",fm[i]+1);
len[i]=strlen(fm[i]+1);
for (j=1;j<=len[i];j++)
s[++l]=fm[i][j];
s[++l]='z'+1;
}
for (i=1;i<=n;i++)
{
p=0;
for (j=1;j<=len[i];j++)
{
x=fm[i][j]-'a'+1;
if (ch[p][x]) p=ch[p][x];
else p=ch[p][x]=++m;
}
pl[i]=p;
b[p]=1;
}
hd=1;
tl=0;
for (i=1;i<=27;i++)
if (ch[0][i])
que[++tl]=ch[0][i];
while (hd<=tl)
{
p=que[hd++];
for (i=1;i<=27;i++)
if (ch[p][i])
{
x=ch[p][i];
que[++tl]=x;
f[x]=ch[f[p]][i];
if (b[f[x]]) la[x]=f[x];
else la[x]=la[f[x]];
}
else ch[p][i]=ch[f[p]][i];
}
for (i=1,p=0;i<=l;i++)
{
x=s[i]-'a'+1;
p=ch[p][x];
if (b[p]) add(p);
else if (la[p]) add(la[p]);
}
for (i=1;i<=n;i++)
printf("%d\n",ans[pl[i]]);
}