hdu 2222AC自动机模板题

点击打开链接

题意:问前面给的所有串在最后一个串出现的次数

思路:这道题是AC自动机入门必做的题,所以没什么好说的,是个模版题,推荐一个大神写的算法详解,不懂得可以看一看,反正我是看他的稍稍懂了点

[html]  view plain  copy
  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <stdlib.h>  
  4. #include <iostream>  
  5. #include <algorithm>  
  6. using namespace std;  
  7. typedef long long ll;  
  8. const int inf=0x3f3f3f3f;  
  9. const int maxn=500010;  
  10. const int N=26;  
  11. struct node{  
  12.     node *fail;  
  13.     node *next[N];  
  14.     int num;  
  15.     node(){  
  16.         fail=NULL;  
  17.         num=0;  
  18.         memset(next,NULL,sizeof(next));  
  19.     }  
  20. }*q[maxn];  
  21. char str1[60],str2[1000010];  
  22. int head,tail;  
  23. void insert_Trie(char *str,node *root){  
  24.     node *p=root;  
  25.     int i=0;  
  26.     while(str[i]){  
  27.         int id=str[i]-'a';  
  28.         if(p->next[id]==NULL) p->next[id]=new node();  
  29.         p=p->next[id];i++;  
  30.     }  
  31.     p->num++;  
  32. }  
  33. void build_ac(node *root){  
  34.     root->fail=NULL;  
  35.     q[head++]=root;  
  36.     while(head!=tail){  
  37.         node *temp=q[tail++];  
  38.         node *p=NULL;  
  39.         for(int i=0;i<N;i++){  
  40.             if(temp->next[i]!=NULL){  
  41.                 if(temp==root) temp->next[i]->fail=root;  
  42.                 else{  
  43.                     p=temp->fail;  
  44.                     while(p!=NULL){  
  45.                         if(p->next[i]!=NULL){  
  46.                             temp->next[i]->fail=p->next[i];  
  47.                             break;  
  48.                         }  
  49.                         p=p->fail;  
  50.                     }  
  51.                     if(p==NULL) temp->next[i]->fail=root;  
  52.                 }  
  53.                 q[head++]=temp->next[i];  
  54.             }  
  55.         }  
  56.     }  
  57. }  
  58. int query(node *root){  
  59.     int i=0,ans=0;  
  60.     node *p=root;  
  61.     while(str2[i]){  
  62.         int id=str2[i]-'a';  
  63.         while(p->next[id]==NULL&&p!=root) p=p->fail;  
  64.         p=p->next[id];  
  65.         p=(p==NULL)?root:p;  
  66.         node *temp=p;  
  67.         while(temp!=root&&temp->num!=-1){  
  68.             ans+=temp->num;  
  69.             temp->num=-1;  
  70.             temp=temp->fail;  
  71.         }  
  72.         i++;  
  73.     }  
  74.     return ans;  
  75. }  
  76. int main(){  
  77.     int T,n;  
  78.     scanf("%d",&T);  
  79.     while(T--){  
  80.         node *root=new node();  
  81.         head=tail=0;  
  82.         scanf("%d",&n);  
  83.         for(int i=0;i<n;i++){  
  84.             scanf("%s",str1);  
  85.             insert_Trie(str1,root);  
  86.         }  
  87.         build_ac(root);  
  88.         scanf("%s",str2);  
  89.         int ans=query(root);  
  90.         printf("%d\n",ans);  
  91.     }  
  92.     return 0;  
  93. }  

点击打开链接
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值