P3796 【模板】AC自动机(加强版)

P3796 【模板】AC自动机(加强版)

https://www.luogu.org/problemnew/show/P3796
 
分析:
  AC自动机。
  建出AC自动机,然后扫一遍文本串,顺着last,统计每个模式串出现的次数。
 
 
代码:
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 
 5 const int N = 150100;
 6 
 7 char str[1000100], s[155][75];
 8 
 9 int ch[N][26], fail[N], val[N], ans[N], q[N], last[N], L, R, Index;
10 
11 void clear() {
12     memset(ch, 0, sizeof(ch));
13     memset(val, 0, sizeof(val));
14     memset(ans, 0, sizeof(ans));
15     memset(last, 0, sizeof(last));
16     memset(fail, 0, sizeof(fail));
17     Index = 0;
18 }
19 void Insert(char *s,int ID) {
20     int u = 0, len = strlen(s);
21     for (int i=0; i<len; ++i) {
22         int c = s[i] - 'a';
23         if (!ch[u][c]) ch[u][c] = ++Index;
24         u = ch[u][c];
25     }
26     val[u] = ID;
27 }
28 void build() {
29     L = 1, R = 0; fail[0] = 0;
30     for (int c=0; c<26; ++c) {
31         int u = ch[0][c];
32         if (u) fail[u] = 0, q[++R] = u, last[u] = 0;
33     }
34     while (L <= R) {
35         int u = q[L++];
36         for (int c=0; c<26; ++c) {
37             int v = ch[u][c];
38             if (!v) {
39                 ch[u][c] = ch[fail[u]][c];
40                 continue;
41             }
42             q[++R] = v;
43             int p = fail[u];
44             while (p && !ch[p][c]) p = fail[p];
45             fail[v] = ch[p][c];
46             last[v] = val[fail[v]] ? fail[v] : last[fail[v]];
47         }
48     }
49 }
50 void find(char *s) {
51     int Ans = 0, u = 0, len = strlen(s);
52     for (int i=0; i<len; ++i) {
53         int c = s[i] - 'a';
54         u = ch[u][c];
55         if (val[u]) ans[val[u]] ++;
56         int p = u;
57         while (last[p]) {
58             p = last[p];
59             if (val[p]) ans[val[p]] ++;
60         }
61     }
62 }
63 int main () {
64     int n;
65     while (~scanf("%d",&n) && n) {
66         clear();
67         for (int i=1; i<=n; ++i) {
68             scanf("%s",s[i]);
69             Insert(s[i], i);
70         }
71         build();
72         scanf("%s",str);
73         find(str);
74         int mx = 0;
75         for (int i=1; i<=n; ++i) mx = max(ans[i], mx);
76         printf("%d\n",mx);
77         for (int i=1; i<=n; ++i) {
78             if (ans[i] == mx) printf("%s\n",s[i]);
79         }
80     }
81     return 0;
82 }

 

posted @ 2018-07-23 17:53  MJT12044  阅读(215)  评论(0编辑  收藏  举报