HDU 3065 病毒侵袭持续中(AC自动机 模板)题解
题意:给出主串中每个模式串的个数
思路:毒瘤出题人多组数据没说给的是多组数据。
板子:
struct Aho{ struct state{ int next[130]; int fail, cnt; }node[maxn]; int size; queue<int> q; void init(){ size = 0; newtrie(); while(!q.empty()) q.pop(); } int newtrie(){ memset(node[size].next, 0, sizeof(node[size].next)); node[size].cnt = node[size].fail = 0; return size++; } void insert(char *s, int id){ int len = strlen(s); int now = 0; for(int i = 0; i < len; i++){ int c = s[i]; if(node[now].next[c] == 0){ node[now].next[c] = newtrie(); } now = node[now].next[c]; } node[now].cnt = id; } void build(){ node[0].fail = -1; q.push(0); while(!q.empty()){ int u = q.front(); q.pop(); for(int i = 0; i < 130; i++){ if(node[u].next[i]){ if(u == 0) node[node[u].next[i]].fail = 0; else{ int v = node[u].fail; while(v != -1){ if(node[v].next[i]){ node[node[u].next[i]].fail = node[v].next[i]; break; } v = node[v].fail; } if(v == -1) node[node[u].next[i]].fail = 0; } q.push(node[u].next[i]); } } } } void get(int u){ //匹配规则 while(u){ if(node[u].cnt) ans[node[u].cnt]++; u = node[u].fail; } } void match(char *s){ int ret = 0, now = 0; int len = strlen(s); for(int i = 0; i < len; i++){ int c = s[i]; if(node[now].next[c]){ now = node[now].next[c]; } else{ int p = node[now].fail; while(p != -1 && node[p].next[c] == 0){ p = node[p].fail; } if(p == -1) now = 0; else now = node[p].next[c]; } get(now); //视情况自己定 } } }ac;
代码:
#include<set> #include<map> #include<cmath> #include<queue> #include<cstdio> #include<vector> #include<cstring> #include <iostream> #include<algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const int maxn = 50000 + 10; const int maxM = 2000000 + 10; const ull seed = 131; const int INF = 0x3f3f3f3f; const int MOD = 1e4 + 7; char s[maxM]; char b[1001][51]; int ans[1001]; struct Aho{ struct state{ int next[130]; int fail, cnt; }node[maxn]; int size; queue<int> q; void init(){ size = 0; newtrie(); while(!q.empty()) q.pop(); } int newtrie(){ memset(node[size].next, 0, sizeof(node[size].next)); node[size].cnt = node[size].fail = 0; return size++; } void insert(char *s, int id){ int len = strlen(s); int now = 0; for(int i = 0; i < len; i++){ int c = s[i]; if(node[now].next[c] == 0){ node[now].next[c] = newtrie(); } now = node[now].next[c]; } node[now].cnt = id; } void build(){ node[0].fail = -1; q.push(0); while(!q.empty()){ int u = q.front(); q.pop(); for(int i = 0; i < 130; i++){ if(node[u].next[i]){ if(u == 0) node[node[u].next[i]].fail = 0; else{ int v = node[u].fail; while(v != -1){ if(node[v].next[i]){ node[node[u].next[i]].fail = node[v].next[i]; break; } v = node[v].fail; } if(v == -1) node[node[u].next[i]].fail = 0; } q.push(node[u].next[i]); } } } } void get(int u){ //匹配规则 while(u){ if(node[u].cnt) ans[node[u].cnt]++; u = node[u].fail; } } void match(char *s){ int ret = 0, now = 0; int len = strlen(s); for(int i = 0; i < len; i++){ int c = s[i]; if(node[now].next[c]){ now = node[now].next[c]; } else{ int p = node[now].fail; while(p != -1 && node[p].next[c] == 0){ p = node[p].fail; } if(p == -1) now = 0; else now = node[p].next[c]; } get(now); } } }ac; int main(){ int n; while(~scanf("%d", &n)){ ac.init(); for(int i = 1; i <= n; i++){ scanf("%s", b[i]); ac.insert(b[i], i); ans[i] = 0; } ac.build(); getchar(); scanf("%s", s); ac.match(s); for(int i = 1; i <= n; i++){ if(ans[i]){ printf("%s: %d\n", b[i], ans[i]); } } } return 0; }