HDU 2222 (AC自动机模板题)

AC自动机裸题,建议刚开始学习的同学看一下这篇博客,讲的很详细   https://blog.csdn.net/u013371163/article/details/60469534

这个是向kuangbin大佬学的写法,感觉很棒啊!

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <cstring>
  4 #include <queue>
  5 using namespace std;
  6 const int MAXN=6e5;
  7 struct Tire
  8 {
  9     int next[MAXN][26],fail[MAXN],last[MAXN];
 10     int L;
 11     int root;
 12     int newnode()
 13     {
 14         for(int i=0;i<26;i++)
 15             next[L][i]=-1;
 16         last[L++]=0;
 17         return L-1;
 18     }
 19     void init()
 20     {
 21         L=0;
 22         root=newnode();
 23     }
 24     void Insert(char *str) //将模式串插入字典树
 25     {
 26         int len=strlen(str);
 27         int now=root;
 28         for(int i=0;i<len;i++)
 29         {
 30             int x=str[i]-'a';
 31             if(next[now][x]==-1)
 32             {
 33                 next[now][x]=newnode();
 34             }
 35             now=next[now][x];
 36         }
 37         last[now]++;
 38     }
 39     void build() //在字典树上建立fail指针
 40     {
 41         int now=root;
 42         int temp;
 43         fail[root]=root; //root的fail指针指向root
 44         queue<int> Q;
 45         for(int i=0;i<26;i++) 
 46         {
 47             if(next[root][i]==-1)
 48                 next[root][i]=root;
 49             else
 50             {
 51                 fail[next[root][i]]=root;
 52                 Q.push(next[root][i]);
 53             }
 54 
 55         }
 56         while(!Q.empty())
 57         {
 58             now=Q.front();
 59             Q.pop();
 60             for(int i=0;i<26;i++)
 61             {
 62                 if(next[now][i]==-1)
 63                     next[now][i]=next[fail[now]][i];
 64                 else
 65                 {
 66                     fail[next[now][i]]=next[fail[now]][i];
 67                     Q.push(next[now][i]);
 68                 }
 69             }
 70         }
 71     }
 72     int query(char *str)
 73     {
 74         int len=strlen(str);
 75         int now=root;
 76         int ans=0;
 77         for(int i=0;i<len;i++)
 78         {
 79             int x=str[i]-'a';
 80             now=next[now][x];
 81             int temp=now;
 82             while(temp!=root)
 83             {
 84                 ans+=last[temp];
 85                 last[temp]=0;
 86                 temp=fail[temp];
 87             }
 88         }
 89         return ans;
 90     }
 91 };
 92 char pattern[MAXN<<2];
 93 Tire ac;
 94 int main()
 95 {
 96     int t,n;
 97     scanf("%d",&t);
 98     while(t--)
 99     {
100         ac.init();
101         scanf("%d",&n);
102         for(int i=0;i<n;i++)
103         {
104             scanf("%s",pattern);
105             ac.Insert(pattern);
106         }
107         ac.build();
108         scanf("%s",pattern);
109         int ans=ac.query(pattern);
110         printf("%d\n",ans);
111     }
112     return 0;
113 }

 

转载于:https://www.cnblogs.com/WOOOOO/p/8890816.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值