2015 多校联赛 ——HDU5384(AC自动机)
Sample Input
1
5 6
orz
sto
kirigiri
danganronpa
ooooo
o
kyouko
dangan
ronpa
ooooo
ooooo
Sample Output
1
1
0
3
7
题意:给n个母串,给m个匹配串,求每个母串依次和匹配串匹配,能得到的数目和
开始用KMP超时了,突然看见AC,把模板改一下就过了- -
#include<iostream> #include<cstdio> #include<cstring> #include<string> using namespace std; #define N 500010 char str[10010], keyword[10005]; char l[100005][10005]; int head, tail; struct node { node *fail; node *next[26]; int count; node() //init { fail = NULL; count = 0; for(int i = 0; i < 26; ++i) next[i] = NULL; } }*q[N]; node *root; void insert(char *str) //建立Trie { int temp, len; node *p = root; len = strlen(str); for(int i = 0; i < len; ++i) { temp = str[i] - 'a'; if(p->next[temp] == NULL) p->next[temp] = new node(); p = p->next[temp]; } p->count++; } void build_ac() { q[tail++] = root; while(head != tail) { node *p = q[head++]; node *temp = NULL; for(int i = 0; i < 26; ++i) { if(p->next[i] != NULL) { if(p == root) p->next[i]->fail = root; else { temp = p->fail; while(temp != NULL) { if(temp->next[i] != NULL) { p->next[i]->fail = temp->next[i]; break; } temp = temp->fail; } if(temp == NULL) p->next[i]->fail = root; } q[tail++] = p->next[i]; //入队 } } } } int query() { int index, len, result; node *p = root; //Tire入口 result = 0; len = strlen(str); for(int i = 0; i < len; ++i) { index = str[i] - 'a'; while(p->next[index] == NULL && p != root) p = p->fail; p = p->next[index]; if(p == NULL) p = root; node *temp = p; while(temp != root && temp->count != -1) { result += temp->count; //temp->count = -1; temp = temp->fail; } } return result; } int main() { int ncase, num,n; scanf("%d", &ncase); while(ncase--) { head= tail = 0; root = new node(); scanf("%d%d", &n,&num); getchar(); for(int i = 1;i <= n;i++) gets(l[i]); for(int i = 0; i < num; ++i) { gets(keyword); insert(keyword); } build_ac(); for(int i = 1; i <= n; i++) { memccpy(str,l[i],0,sizeof(l[i])); //build_ac(); printf("%d\n", query()); } } return 0; }