AC自动机 模板 hdu 2896

来源:互联网 发布:网络剧合作平台 编辑:程序博客网 时间:2024/06/06 17:47

#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>using namespace std;const int N=128;struct node{node *fail;node *next[N];int count;node(){fail=NULL;count=0;memset(next,NULL,sizeof(next));}}*q[500005];char key[205],model[10005];int num[50005];int head,tail;void insert(char *s,node *root,int ant){node *p = root;int i = 0,k;int len=strlen(s);for(i = 0 ; i < len ; i ++){k = s[i];if(p->next[k] == NULL)p->next[k] = new node();p = p->next[k];}p->count=ant;}void build_fail(node *root){int i;q[tail ++] = root;while(head != tail){node *temp = q[head ++];node *p=NULL;for(i = 0 ; i < 128 ; i ++){if(temp->next[i] != NULL){    if(temp == root)   temp->next[i]->fail=root;    else    { p = temp->fail;     //p指向当前结点的fail指针  while(p != NULL) //向根节点回溯,找父节点的fail指针指向的节点下有没有相等的前缀 {if(p->next[i] != NULL)  //找到相等的节点{temp->next[i]->fail = p->next[i]; //将fail指针指向想等的节点break;}p = p->fail;//p指向自身的fail,如果p为root,p->fail为NULL,则p为NULL }      if(p == NULL) //temp的fai指针指向的结点下没有相等的节点,fail指向root  temp->next[i]->fail = root;    }    q[tail ++] = temp->next[i];//下一个节点入队列}}}}int query(node *root){int i = 0,j=0,k,len = strlen(model);//int flag = 0;node *p = root;for(i = 0 ; i < len ; i++){k=model[i];while(p != root && p->next[k] == NULL) //如果p指向的节点为NULL,p就指向它的fail指针p = p->fail;p = p->next[k];p = (p == NULL) ? root : p; //如果p的next[k]为NULL,p就指回root,反之p指向next[k]node *temp = p;while(temp != root){if(temp->count){num[j ++] = temp->count;}temp=temp->fail;}}//printf("~~~~~~~~~%d\n",j);return j;}int main(){   // freopen("Input.txt","r",stdin);   // freopen("Output.txt","w",stdout);int n,m,i,j,k;while(~scanf("%d",&n)){head=tail=0;node *root = new node();for(i = 1 ; i <= n ; i++){scanf("%s",key);insert( key , root , i);}build_fail(root);scanf("%d",&m);int total=0;for(j = 1 ; j <= m; j++){scanf("%s",model);memset(num,0,sizeof(num));k=query(root);if(k){printf("web %d:",j);sort(num,num+k);printf(" %d",num[0]);for(i=1;num[i]!=0;i++){    if(num[i]!=num[i-1])        printf(" %d",num[i]);}printf("\n");total++;}}printf("total: %d\n",total);}return 0;}


原创粉丝点击