码迷,mamicode.com
首页 > 其他好文 > 详细

【模板】AC自动机

时间:2017-04-23 16:52:58      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:iostream   ios   http   lin   span   i++   rip   初学者   size   

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自动机

标签:iostream   ios   http   lin   span   i++   rip   初学者   size   

原文地址:http://www.cnblogs.com/zhenghaotian/p/6751904.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!