hdu 3065 病毒侵襲持續中 (AC自動機)
阿新 • • 發佈:2020-12-25
題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=3065
多測
卡記憶體
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<cmath> #include<queue> using namespace std; typedef long long ll; const int maxn = 100100; int n, rt = 0, tot = 0; int ans[maxn]; struct Node{ int son[30], en, fail; }t[maxn]; char s[1010][55]; char txt[2000010]; void insert(int num){ int p = rt; int len = strlen(s[num]); for(int i = 0 ; i < len ; ++i){ if(!t[p].son[s[num][i] - 'A']){ t[p].son[s[num][i] - 'A'] = ++tot; } p = t[p].son[s[num][i] - 'A']; } t[p].en = num; } void build(){ queue<int> q; t[rt].fail = rt; for(int i = 0 ; i <= 25 ; ++i){ if(t[rt].son[i]) q.push(t[rt].son[i]); } while(!q.empty()){ int u = q.front(); q.pop(); for(int i = 0 ; i <= 25 ; ++i){ if(t[u].son[i]){ t[t[u].son[i]].fail = t[t[u].fail].son[i]; q.push(t[u].son[i]); } else{ t[u].son[i] = t[t[u].fail].son[i]; } } } } void query(){ int p = rt; int len = strlen(txt); for(int i = 0 ; i < len ; ++i){ if(txt[i] < 'A' || txt[i] > 'Z') p = 0; else p = t[p].son[txt[i] - 'A']; for(int j = p ; j ; j = t[j].fail) { ++ans[t[j].en]; } } } ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; } int main(){ while(scanf("%d", &n) != EOF && n){ memset(ans, 0, sizeof(ans)); tot = 0; memset(t, 0, sizeof(t)); for(int i = 1 ; i <= n ; ++i){ scanf("%s", s[i]); insert(i); } build(); scanf("%s", txt); query(); for(int i = 1 ; i <= n ; ++i){ if(ans[i]) { printf("%s: %d\n", s[i], ans[i]); } } } return 0; }