模板AC自动机

Posted 蒟蒻zht的博客

tags:

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

Keywords Search

一道模板题,但对于我这种初学者来说也是不好做的。

对于AC自动机的理解,本蒟蒻暂时还理解不好,不多说了。

看看这个人的blog

——本题代码

技术分享
 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <queue>
 5 #define N 500005
 6 
 7 using namespace std;
 8 
 9 char s[N << 1];
10 int T, n, sz, ans;
11 int ch[N][26], val[N], fail[N];
12 bool vis[N];
13 queue <int> q;
14 
15 inline void clear()
16 {
17     n = sz = ans = 0;
18     memset(ch, 0, sizeof(ch));
19     memset(vis, 0, sizeof(vis));
20     memset(val, 0, sizeof(val));
21     memset(fail, 0, sizeof(fail));
22 }
23 
24 inline void insert()
25 {
26     int i, x, len = strlen(s), now = 0;
27     for(i = 0; i < len; i++)
28     {
29         x = s[i] - a;
30         if(!ch[now][x]) ch[now][x] = ++sz;
31         now = ch[now][x];
32     }
33     val[now]++;
34 }
35 
36 inline void make_fail()
37 {
38     int i, now;
39     while(!q.empty()) q.pop();
40     //第二层特殊处理,将第二层节点的 fail 指针指向 root(其实就是0,也就不用管) 
41     for(i = 0; i < 26; i++) 
42      if(ch[0][i])
43       q.push(ch[0][i]);
44     while(!q.empty())
45     {
46         now = q.front(), q.pop();
47         for(i = 0; i < 26; i++)
48         {
49             if(!ch[now][i])
50             {
51                 ch[now][i] = ch[fail[now]][i];
52                 continue;
53             }
54             fail[ch[now][i]] = ch[fail[now]][i];
55             q.push(ch[now][i]);
56         }
57     }
58 }
59 
60 inline void ac()
61 {
62     int x, y, len = strlen(s), i, now = 0;
63     for(i = 0; i < len; i++)
64     {
65         vis[now] = 1;
66         x = s[i] - a;
67         y = ch[now][x];
68         while(y && !vis[y])
69         {
70             vis[y] = 1;
71             ans += val[y];
72             y = fail[y];
73         }
74         now = ch[now][x];
75     }
76 }
77 
78 int main()
79 {
80     int i;
81     scanf("%d", &T);
82     while(T--)
83     {
84         clear();
85         scanf("%d", &n);
86         for(i = 1; i <= n; i++)
87         {
88             scanf("%s", s);
89             insert();
90         }
91         scanf("%s", s);
92         make_fail();
93         ac();
94         printf("%d\n", ans);
95     }
96     return 0;
97 }
View Code

 

以上是关于模板AC自动机的主要内容,如果未能解决你的问题,请参考以下文章

HDU3247 Resource Archiver(AC自动机+BFS+DP)

模板AC自动机

HDU-2222-Keywords Search(AC自动机模板)

POJ3691DNA repair(AC自动机,DP)

HDU4057 Rescue the Rabbit(AC自动机+状压DP)

P3796 模板AC自动机(加强版) 题解(Aho-Corasick Automation)