AC自动机 P3808

前置知识:

1.KMP

2.Trie

 

其实我就是来贴个代码的好吧。

代码主要内容:

1.建Trie树

2.Getfail(得到fail值)

3.query

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 1e7 + 5;
 4 int n;
 5 char s[N];
 6 int Trie[N][27], val[N], fail[N];
 7 int cnt = 0;
 8 
 9 void build(void)
10 {
11     int len = strlen(s);
12     int now = 0;
13     for (int i = 0; i < len; i++)
14     {
15         if (!Trie[now][s[i] - 'a'])
16         {
17             Trie[now][s[i] - 'a'] = ++cnt;
18         }
19         now = Trie[now][s[i] - 'a'];
20     }
21     val[now]++;
22     return;
23 }
24 
25 void Getfail(void)
26 {
27     queue<int> q;
28     for (int i = 0; i < 26; i++)
29     {
30         if (Trie[0][i])
31         {
32             fail[Trie[0][i]] = 0;
33             q.push(Trie[0][i]);
34         }
35     }
36     while (!q.empty())
37     {
38         int head = q.front();
39         q.pop();
40         for (int i = 0; i < 26; i++)
41         {
42             if (Trie[head][i])
43             {
44                 fail[Trie[head][i]] = Trie[fail[head]][i];
45                 q.push(Trie[head][i]);
46             }
47             else
48                 Trie[head][i] = Trie[fail[head]][i];
49         }
50     }
51     return;
52 }
53 
54 int query(void)
55 {
56     int len = strlen(s);
57     int now = 0, ans = 0;
58     for (int i = 0; i < len; i++)
59     {
60         now = Trie[now][s[i] - 'a'];
61         for (int j = now; val[j] != -1; j = fail[j])
62             ans += val[j], val[j] = -1;
63     }
64     return ans;
65 }
66 
67 int main(void)
68 {
69     scanf("%d", &n);
70     for (int i = 1; i <= n; i++)
71     {
72         scanf("%s", s);
73         build();
74     }
75     Getfail();
76     scanf("%s", s);
77     printf("%d\n", query());
78     return 0;
79 }

 

 
posted @ 2020-10-01 18:15  luyiming123  阅读(107)  评论(0编辑  收藏  举报