【AC自动机】bzoj3172: [Tjoi2013]单词

fail图上后缀和需要注意一下

Description

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

Input

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

Output

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

Sample Input

3
a
aa
aaa

Sample Output

6
3
1

题目分析

考虑暴力:将每一个单词作为文本串匹配,一旦遇到一个单词节点,就向上跳fail统计整条链上的所有单词的贡献。

注意到对于每一个匹配到的单词节点,有一个向上的后缀和的形式在这里。

那么从另一个方式考虑,对于每一个节点,计算有多少子节点会把它统计进答案里。

这样就可以用很自然的fail后缀和来处理这个问题了。

注意

要注意的是,trie图后缀和的统计顺序不能够简单地根据tot...1的顺序。

因为trie图是有分叉的,节点的标号与深度并无关系。

 1 #include<bits/stdc++.h>
 2 const int maxn = 203;
 3 const int maxNode = 1000035;
 4 
 5 struct ACAutomaton
 6 {
 7     char s[maxn];
 8     int vis[maxNode];
 9     std::queue<int> q;
10     int stk[maxNode],cnt;
11     int fail[maxNode],f[maxNode][30],size[maxNode],tot,n;
12     void insert(char *s, int t)
13     {
14         int u = 1, lens = strlen(s);
15         for (int i=0; i<lens; i++)
16         {
17             int c = s[i]-'a';
18             if (!f[u][c]) f[u][c] = ++tot;
19             u = f[u][c], size[u]++;
20         }
21         vis[t] = u;
22 //        vis[u]++;
23     }
24     void count()      //其实这里写的冗长了一点
25     {             //如果用手写的队列就不用再开一个数组了
26         for (int i=tot; i>1; i--)
27             size[fail[stk[i]]] += size[stk[i]];
28     }
29     void build()
30     {
31         for (int i=0; i<=25; i++) f[0][i] = 1;
32         q.push(1);
33         while (q.size())
34         {
35             int tt = q.front();
36             q.pop();
37             stk[++cnt] = tt;
38             for (int i=0; i<=25; i++)
39                 if (f[tt][i])
40                     fail[f[tt][i]] = f[fail[tt]][i], q.push(f[tt][i]);
41                 else f[tt][i] = f[fail[tt]][i];
42         }
43     }
44 }f;
45 int n;
46 char s[1000035]; 
47 
48 int main()
49 {
50     scanf("%d",&n);
51     f.tot = 1;
52     for (int i=1; i<=n; i++)
53         scanf("%s",s), f.insert(s, i);
54     f.build(), f.count();
55     for (int i=1; i<=n; i++) printf("%d\n",f.size[f.vis[i]]);
56     return 0;
57 }

 

 

END

posted @ 2018-09-06 20:29  AntiQuality  阅读(199)  评论(0编辑  收藏  举报