标签:直接 存储 文本 pts marked log next 基础 printf
这是一道简单的AC自动机模板题。
用于检测正确性以及算法常数。
为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交。
管理员提示:本题数据内有重复的单词,且重复单词应该计算多次,请各位注意
给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过。
第一行一个n,表示模式串个数;
下面n行每行一个模式串;
下面一行一个文本串。
一个数表示答案
2 a aa aa
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; }
标签:直接 存储 文本 pts marked log next 基础 printf
原文地址:https://www.cnblogs.com/hrj1/p/11135456.html