【AC自动机】洛谷 P3796 【模板】AC自动机(加强版)
2021-09-26 10:59:00
# ACM
题链
题目解析 多模式串匹配,使用$AC$自动机,模板题;
学自 $OI-wiki$
代码实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 #include <bits/stdc++.h> using namespace std; #define LL long long #define ULL unsigned long long #define ls rt<<1 #define rs rt<<1|1 #define B1 131 #define B2 13331 #define M1 1000000007 #define M2 1000000009 #define eps 1e-8 #define MAXN 9e18 #define MS 1000009 int n,m,k;struct node { char s[100 ]; }p[200 ]; int cnt[200 ];char s[MS];int dic[MS][26 ], ext_id[MS], fail[MS], tot;queue<int > Q; void insert (char *s, int len, int id) { int u = 0 ; for (int i=0 ;i<len;i++){ int c = s[i]-'a' ; if (!dic[u][c]) dic[u][c] = ++tot; u = dic[u][c]; } ext_id[u] = id; } void build () { for (int i=0 ;i<26 ;i++){ if (dic[0 ][i]) Q.push (dic[0 ][i]); } while (!Q.empty ()){ int u = Q.front (); Q.pop (); for (int i=0 ;i<26 ;i++){ if (dic[u][i]){ fail[dic[u][i]] = dic[fail[u]][i]; Q.push (dic[u][i]); } else { dic[u][i] = dic[fail[u]][i]; } } } } void query (char *s, int len) { for (int i=0 ,u=0 ,c;i<len;i++){ c = s[i]-'a' ; u = dic[u][c]; for (int j=u;j;j=fail[j]){ cnt[ext_id[j]]++; } } } void clear () { memset (cnt, 0 , sizeof cnt); memset (dic, 0 , sizeof dic); memset (ext_id, 0 , sizeof ext_id); memset (fail, 0 , sizeof fail); tot = 0 ; } void solve () { for (int i=1 ;i<=n;i++){ cin >> p[i].s; insert (p[i].s, strlen (p[i].s), i); } build (); cin >> s; query (s, strlen (s)); int maxn = 0 ; for (int i=1 ;i<=n;i++) maxn = max (maxn, cnt[i]); cout << maxn << "\n" ; for (int i=1 ;i<=n;i++){ if (cnt[i] == maxn){ cout << p[i].s << "\n" ; } } clear (); } int main () { ios::sync_with_stdio (false ); int ce = 1 ; while (cin >> n && n){ solve (); } }
2021-09-26 10:59:00
# ACM