bzoj3172 [Tjoi2013]单词
Description
某人读论文,一篇论文是由许多单词组成。但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次。
Input
第一个一个整数N,表示有多少个单词,接下来N行每行一个单词。每个单词由小写字母组成,N<=200,单词长度不超过10^6
Output
输出N个整数,第i行的数字表示第i个单词在文章中出现了多少次。
Sample Input
3
a
aa
aaa
a
aa
aaa
Sample Output
6
3
1
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 inline 17 #define RG register 18 #define ll long long 19 #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 }