HDU 3065 病毒侵袭持续中(AC自动机)

来源:互联网 发布:学做淘宝到哪里去学 编辑:程序博客网 时间:2024/06/05 02:16

题目链接:HDU 3065


AC自动机第二题~

模板几乎没有改动,只是模式字符串中出现了字母以外的字符需要处理一下,还有需要将计数的标记取消。

源代码

#include <iostream>#include <cstring>#include <cstdio>using namespace std;const int kind = 27;struct node{node *next[kind];int count ;node* fail;node(){count = 0;fail = NULL;memset(next,0,sizeof(next));}}*q[5000000];int ans[1111];node *root;int head,tail;char word[1010][55];char str[2000010];void insert(char *s,int k){ //构建trieint len = strlen(s);node *p = root;for(int i=0;i<len;i++){int index = s[i]-'A';if(!p->next[index])p->next[index] = new node;p=p->next[index];}p->count = k;}void build_ac_automation(){ //初始化fail指针q[tail++] = root;while(head<tail){node *p = q[head++];node *tmp = NULL;for(int i=0;i<kind;i++){if(p->next[i] != NULL){if(p == root)//首元素必须指根p->next[i]->fail = root;else{tmp =  p->fail; //失败指针(跳转指针)while(tmp != NULL){if(tmp->next[i] != NULL){//找到匹配p->next[i]->fail = tmp->next[i];break;} //如果没找到,则继续向上一个失败指针找tmp = tmp->fail;}if(tmp == NULL) //为空 则从头匹配p->next[i]->fail = root;}q[tail++] = p->next[i];//下一层入队}}}}void query(){int len = strlen(str);node *p = root;int cnt = 0;int index;for(int i=0;i<len;i++){if(str[i]<'A' || str[i] > 'Z')index = 26;elseindex = str[i]-'A';while(p->next[index] == NULL && p!=root)p = p->fail;p = p->next[index];if(p == NULL)p = root;node *tmp = p;//tmp 动 , p不动。while(tmp != root && tmp->count != 0){ans[tmp->count]++;tmp = tmp ->fail; }}}void clear(node *root){if(!root)return ;else{for(int i=0;i<kind;i++)clear(root->next[i]);}delete(root);}int main(){int n;while(scanf("%d",&n)!=EOF){memset(ans,0,sizeof(ans));root = new node;getchar();for(int i=0;i<n;i++){gets(word[i]);insert(word[i],i+1);}gets(str);head = tail = 0;build_ac_automation();query();int m;for(int i=1;i<=n;i++){if(ans[i]){printf("%s: %d\n",word[i-1],ans[i]);}}clear(root);}return 0;}


1 0
原创粉丝点击