首页 > 代码库 > bzoj3172 [Tjoi2013]单词

bzoj3172 [Tjoi2013]单词

Description

某人读论文,一篇论文是由许多单词组成。但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次。

Input

第一个一个整数N,表示有多少个单词,接下来N行每行一个单词。每个单词由小写字母组成,N<=200,单词长度不超过10^6

Output

输出N个整数,第i行的数字表示第i个单词在文章中出现了多少次。

Sample Input

3
a
aa
aaa

Sample Output

6
3
1

 

正解:$AC$自动机。

$AC$自动机板子题。刚刚复习了一下,基本上还记得,只是$last$数组那里忘了,不过这题也不需要。。

直接构出$trie$树和$fail$树,然后按照$fail$树自底向上更新单词数量就行了。

 

 1 //It is made by wfj_2048~ 2 #include <algorithm> 3 #include <iostream> 4 #include <complex> 5 #include <cstring> 6 #include <cstdlib> 7 #include <cstdio> 8 #include <vector> 9 #include <cmath>10 #include <queue>11 #include <stack>12 #include <map>13 #include <set>14 #define inf (1<<30)15 #define N (1000010)16 #define il inline17 #define RG register18 #define ll long long19 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)20 21 using namespace std;22 23 int q[N],pos[210],n,len;24 char s[N];25 26 struct AC_auto{27 28     int ch[N][26],val[N],nxt[N],last[N],sz;29     30     il void insert(char *s,RG int len,RG int p){31     RG int x=0,c;32     for (RG int i=1;i<=len;++i){33         c=s[i]-97; if (!ch[x][c]) ch[x][c]=++sz;34         x=ch[x][c],val[x]++;35     }36     pos[p]=x; return;37     }38     39     il void build(){40     RG int h=0,t=0;41     for (RG int c=0;c<26;++c)42         if (ch[0][c]) nxt[ch[0][c]]=last[ch[0][c]]=0,q[++t]=ch[0][c];43     while (h<t){44         RG int x=q[++h],v,j;45         for (RG int c=0;c<26;++c){46         v=ch[x][c];47         if (!v){ ch[x][c]=ch[nxt[x]][c]; continue; }48         q[++t]=v,j=nxt[x]; while (j && !ch[j][c]) j=nxt[j];49         nxt[v]=ch[j][c],last[v]=val[nxt[v]] ? nxt[v] : last[nxt[v]];50         }51     }52     for (RG int i=t;i;--i) val[nxt[q[i]]]+=val[q[i]]; return;53     }54     55 }AC;56 57 il int gi(){58     RG int x=0,q=1; RG char ch=getchar();59     while ((ch<0 || ch>9) && ch!=-) ch=getchar();60     if (ch==-) q=-1,ch=getchar();61     while (ch>=0 && ch<=9) x=x*10+ch-48,ch=getchar();62     return q*x;63 }64 65 il void work(){66     n=gi();67     for (RG int i=1;i<=n;++i){68     scanf("%s",s+1),len=strlen(s+1);69     AC.insert(s,len,i);70     }71     AC.build();72     for (RG int i=1;i<=n;++i)73     printf("%d\n",AC.val[pos[i]]);74     return;75 }76 77 int main(){78     File("word");79     work();80     return 0;81 }

 

bzoj3172 [Tjoi2013]单词