3172. [TJOI2013]单词AC自动机

Posted Refun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了3172. [TJOI2013]单词AC自动机相关的知识,希望对你有一定的参考价值。

Description

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

Input

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

Output

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

Sample Input

3
a
aa
aaa

Sample Output

6
3
1
 
还是对AC自动机的理解不够到位啊=-=……
其实fail指针也是一颗树,而fail树有一些神奇的性质
根节点仍然是0,每一个fail指针指向自己的最长后缀
也就是说,我们把每个节点的权值设为1,然后再处理一下fail树的子树和
如何处理呢?在build_fail的时候记录一下经过节点的顺序,
然后倒序枚举,将当前枚举到的点的fail指针指向的点的权值累加一下
最开始记录一下每个单词的位置,方便输出。
 
 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<queue>
 5 #define N (1000000+100)
 6 using namespace std;
 7 int Son[N][27],Fail[N],End[N];
 8 int n,sz,ans[N],pos[N],Q[N],cnt;
 9 bool vis[N],flag;
10 char s[N],ask[N];
11 queue<int>q;
12 void Insert(char s[],int &pos)
13 {
14     int now=0,len=strlen(s);
15     for (int i=0; i<len; ++i)
16     {
17         int x=s[i]-a;
18         if (!Son[now][x]) Son[now][x]=++sz;
19         now=Son[now][x];
20         ++ans[now];
21     }
22     pos=now;
23 }
24 
25 void Build_Fail()
26 {
27     for (int i=0;i<26;++i)
28         if (Son[0][i])
29             q.push(Son[0][i]);
30     while (!q.empty())
31     {
32         int now=q.front(); q.pop();
33         Q[++cnt]=now;
34         for (int i=0;i<26;++i)
35         {
36             if (!Son[now][i])
37             {
38                 Son[now][i]=Son[Fail[now]][i];
39                 continue;
40             }
41             Fail[Son[now][i]]=Son[Fail[now]][i];
42             q.push(Son[now][i]);
43         }
44     }    
45 }
46 
47 void Query()
48 {
49     for (int i=cnt;i>=1;--i)
50         ans[Fail[Q[i]]]+=ans[Q[i]];
51     for (int i=1;i<=n;++i)
52         printf("%d\n",ans[pos[i]]);
53 }
54 int main()
55 {
56     scanf("%d",&n);
57     for (int i=1;i<=n;++i)
58         scanf("%s",s),Insert(s,pos[i]);
59     Build_Fail();
60     Query();
61 }

以上是关于3172. [TJOI2013]单词AC自动机的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 3172: [Tjoi2013]单词 [AC自动机 Fail树]

bzoj3172: [Tjoi2013]单词 字符串-AC自动机

3172. [TJOI2013]单词AC自动机

BZOJ 3172 [Tjoi2013]单词 AC自动机Fail树

BZOJ 3172: [Tjoi2013]单词

[BZOJ3172 ][Tjoi2013]单词(AC自动机)