标签:
题意:训练之南(P216)
分析:求出现最多次数的字串,那么对每个字串映射id,cnt记录次数求最大就可以了。
#include <bits/stdc++.h> using namespace std; const int N = 150 + 5; const int NODE = N * 70; const int LEN = 1e6 + 5; const int SIZE = 26; struct AC { int ch[NODE][SIZE], fail[NODE], val[NODE], cnt[N], sz; map<string, int> ms; void clear(void) { memset (ch[0], 0, sizeof (ch[0])); memset (cnt, 0, sizeof (cnt)); sz = 1; val[0] = 0; ms.clear (); } int idx(char c) { return c - ‘a‘; } void insert(char *P, int id) { ms[string (P)] = id; int u = 0; for (int c, i=0; P[i]; ++i) { c = idx (P[i]); if (!ch[u][c]) { memset (ch[sz], 0, sizeof (ch[sz])); val[sz] = 0; ch[u][c] = sz++; } u = ch[u][c]; } val[u] = id; } void build(void) { queue<int> que; fail[0] = -1; int u; for (int i=0; i<SIZE; ++i) { u = ch[0][i]; if (u) { fail[u] = 0; que.push (u); } } while (!que.empty ()) { u = que.front (); que.pop (); for (int i=0; i<SIZE; ++i) { int &v = ch[u][i]; if (!v) { v = ch[fail[u]][i]; continue; } que.push (v); fail[v] = ch[fail[u]][i]; } } } void query(char *T) { int u = 0, v; for (int c, i=0; T[i]; ++i) { c = idx (T[i]); u = ch[u][c]; v = u; cnt[val[v]]++; } } }ac; char pattern[N][75], text[LEN]; int n; void solve(void) { int best = -1; for (int i=1; i<=n; ++i) { if (ac.cnt[i] > best) best = ac.cnt[i]; } printf ("%d\n", best); for (int i=1; i<=n; ++i) { if (ac.cnt[ac.ms[string (pattern[i])]] == best) { printf ("%s\n", pattern[i]); } } } int main(void) { while (scanf ("%d", &n) == 1) { if (!n) break; ac.clear (); for (int i=1; i<=n; ++i) { scanf ("%s", &pattern[i]); ac.insert (pattern[i], i); } ac.build (); scanf ("%s", &text); ac.query (text); solve (); } return 0; }
AC自动机 LA 4670 Dominating Patterns
标签:
原文地址:http://www.cnblogs.com/Running-Time/p/5123692.html