hdu 2222 AC自动机

xiaoxiao2021-02-28  126

传送门 : HDU 2222

注意有相同模式串出现的可能, 且每个串最多记一次答案

code:

#include <iostream> #include <cstdio> #include <cstring> #include <string> using namespace std; #define clr(a) memset(a, 0, sizeof a) const int N = 10010 * 50; struct AC_Auto{ int ch[N][26], f[N], v[N], last[N], sz, q[N]; void init(){ clr(ch); clr(f); clr(v); clr(q); clr(last); /**clr(vis);*/ sz = 1; } void insert(string s){ int len = s.length(); int u = 0; for(int i = 0; i < len; ++i){ int c = s[i] - 'a'; if(!ch[u][c]) ch[u][c] = sz++; u = ch[u][c]; } ++v[u]; last[u] = 1; } void getFail(){ q[0] = 0; int now = 0, top = 1; while(now < top){ int t = q[now++]; for(int i = 0; i < 26; ++i){ if(ch[t][i]){ int p = ch[t][i], u = f[t]; while(!ch[u][i] && u) u = f[u]; f[p] = t == 0 ? 0 : ch[u][i]; last[p] |= last[f[p]]; /**v[p] = v[p] || v[f[p]];*/ q[top++] = p; } else ch[t][i] = ch[f[t]][i]; } } } int dfs(int x){ if(!last[x]) return 0; //vis[x] = 1; int ret = 0; ret += v[x] + dfs(f[x]); v[x] = 0;/**记过答案清掉标记1*/ return ret; } int cal(string s){ int u = 0, ans = 0; for(int i = 0; i < s.length(); ++i){ u = ch[u][s[i] - 'a']; if(last[u]) ans += dfs(u); } return ans; } }ac; int main(){   //freopen("in.txt", "r", stdin); int t, n; string s; cin >> t; while(t--){ ac.init(); cin >> n; for(int i = 0; i < n; ++i){ cin >> s; ac.insert(s); } ac.getFail(); cin >> s; cout << ac.cal(s) << endl; } return 0; }
转载请注明原文地址: https://www.6miu.com/read-40727.html

最新回复(0)