模板AC自动机(简单版)
Posted hrj1
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板AC自动机(简单版)相关的知识,希望对你有一定的参考价值。
题目背景
通过套取数据而直接“打表”过题者,是作弊行为,发现即棕名。
这是一道简单的AC自动机模板题。
用于检测正确性以及算法常数。
为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交。
管理员提示:本题数据内有重复的单词,且重复单词应该计算多次,请各位注意
题目描述
给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过。
输入格式
第一行一个n,表示模式串个数;
下面n行每行一个模式串;
下面一行一个文本串。
输出格式
一个数表示答案
输入输出样例
输入 #1
2 a aa aa
输出 #1
2
说明/提示
subtask1[50pts]:∑length(模式串)<=10^6,length(文本串)<=10^6,n=1;
subtask2[50pts]:∑length(模式串)<=10^6,length(文本串)<=10^6;
这难度算简单版???我已经不想做加强版了
所以可以简单的理解为将KMP放在Trie树上。
注意如果每次跳fail边复杂度过高,一次存储完可以进行优化。
这样的AC自动机就成为了Trie图。
不懂Trie图的自行百度(我也是自学了40分钟才搞懂,感觉整个人要炸了)
友情链接:https://www.cnblogs.com/cmmdc/p/7337611.html
#include<cstdio> #include<cstring> #include<queue> using namespace std; int n,ch[5000005][30]; int t,f[5000005],next[5000005]; char s[1000005]; inline void add() int len=strlen(s+1),hhh=1; for(int i=1;i<=len;i++) int u=s[i]-‘a‘; if(!ch[hhh][u]) ch[hhh][u]=++t; hhh=ch[hhh][u]; f[hhh]++; queue<int>q; inline void getnext() for(int i=0;i<26;i++)ch[0][i]=1; next[1]=0; q.push(1); while(!q.empty()) int x=q.front(); q.pop(); for(int i=0;i<26;i++) int u=ch[x][i]; if(!u) ch[x][i]=ch[next[x]][i]; else int p=next[x]; q.push(u); next[u]=ch[p][i]; inline int find() int len=strlen(s+1); int i=1,hhh=1,q,w,ans=0; while(i<=len) q=s[i]-‘a‘; w=ch[hhh][q]; while(w>1) if(f[w]==-1) break; ans+=f[w]; f[w]=-1; w=next[w]; hhh=ch[hhh][q]; i++; return ans; int main() scanf("%d",&n); t=1; for(int i=1;i<=n;i++) scanf("%s",s+1); add(); getnext(); scanf("%s",s+1); printf("%d\\n",find()); return 0;
以上是关于模板AC自动机(简单版)的主要内容,如果未能解决你的问题,请参考以下文章