首页 > 代码库 > AC自动机

AC自动机

1 Dominating Patterns UVALive 4670

技术分享
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <algorithm>
  6 #include <queue>
  7 #include <vector>
  8 #include <stack>
  9 #include <map>
 10 #include <set>
 11 #include <cmath>
 12 #include <cctype>
 13 #include <ctime>
 14 
 15 using namespace std;
 16 
 17 #define REP(i, n) for (int i = 0; i < (n); ++i)
 18 #define eps 1e-9
 19 
 20 typedef long long ll;
 21 typedef pair<int, int> pii;
 22 
 23 const int INF = 0x7fffffff;
 24 const int maxn = 1e6 + 10;
 25 const int maxnode = 2e4;
 26 char str[maxn], str_t[160][80];
 27 int n, sz;
 28 int ch[maxnode][26], fail[maxnode], val[maxnode], last[maxnode], cnt[160];
 29 map<string, int> m;
 30 
 31 inline void init() {
 32     sz = 1; memset(ch[0], 0, sizeof(ch[0]));
 33     memset(cnt, 0, sizeof(cnt)); m.clear();
 34 }
 35 inline int get_id(char c) { return c - a; }
 36 void insert(char *s, int _val) {
 37     int u = 0, len_t = strlen(s), id;
 38     for (int i = 0; i < len_t; ++i) {
 39         id = get_id(s[i]);
 40         if (!ch[u][id]) {
 41             memset(ch[sz], 0, sizeof(ch[sz]));
 42             val[sz] = 0; ch[u][id] = sz++;
 43         }
 44         u = ch[u][id];
 45     }
 46     val[u] = _val; m[s] = _val;
 47 }
 48 void print(int j) {
 49     if (j) { ++cnt[val[j]]; print(last[j]); }
 50 }
 51 int find(char *T) {
 52     int len_T = strlen(T), j = 0, id;
 53     for (int i = 0; i < len_T; ++i) {
 54         id = get_id(T[i]);
 55         while (j && !ch[j][id]) { j = fail[j]; }
 56         j = ch[j][id];
 57         if (val[j]) { print(j); }
 58         else if (last[j]) { print(last[j]); }
 59     }
 60 }
 61 void get_fail() {
 62     queue<int> q; fail[0] = 0; int u, v, f;
 63     for (int c = 0; c < 26; ++c) {
 64         u = ch[0][c];
 65         if (u) { fail[u] = 0; q.push(u); last[u] = 0; }
 66     }
 67     while (!q.empty()) {
 68         f = q.front(); q.pop();
 69         for (int c = 0; c < 26; ++c) {
 70             u = ch[f][c]; if (!u) { continue; }
 71             q.push(u); v = fail[f];
 72             while (v && !ch[v][c]) { v = fail[v]; }
 73             fail[u] = ch[v][c];
 74             last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
 75         }
 76     }
 77 }
 78 
 79 int main() {
 80 #ifdef __AiR_H
 81     freopen("in.txt", "r", stdin);
 82 //    freopen("out.txt", "w", stdout);
 83 #endif // __AiR_H
 84     while (scanf("%d", &n) && n) {
 85         init();
 86         for (int i = 1; i <= n; ++i) {
 87             scanf("%s", str_t[i]); insert(str_t[i], i);
 88         }
 89         get_fail();
 90         scanf("%s", str); find(str);
 91         int ans = 0;
 92         for (int i = 1; i <= n; ++i) {
 93             if (cnt[i] > ans) { ans = cnt[i]; }
 94         }
 95         printf("%d\n", ans);
 96         for (int i = 1; i <= n; ++i) {
 97             if (cnt[m[str_t[i]]] == ans) { printf("%s\n", str_t[i]); }
 98         }
 99     }
100 #ifdef __AiR_H
101     printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);
102 #endif // __AiR_H
103     return 0;
104 }
View Code

 

AC自动机