【模板】AC自动机
2017-08-08 17:26
417 查看
来自洛谷的两道AC自动机模板题;
用于检测正确性以及算法常数。
为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交。
管理员提示:本题数据内有重复的单词,且重复单词应该计算多次,请各位注意
第一行一个n,表示模式串个数;
下面n行每行一个模式串;
下面一行一个文本串。
输出格式:
一个数表示答案
输出样例#1:
subtask2[50pts]:∑length(模式串)<=10^6,length(文本串)<=10^6;
代码实现
输入含多组数据。
每组数据的第一行为一个正整数NNN,表示共有NNN个模式串,1≤N≤1501 \leq N \leq 1501≤N≤150。
接下去NNN行,每行一个长度小于等于707070的模式串。下一行是一个长度小于等于10610^6106的文本串TTT。
输入结束标志为N=0N=0N=0。
输出格式:
对于每组数据,第一行输出模式串最多出现的次数,接下去若干行每行输出一个出现次数最多的模式串,按输入顺序排列。
输出样例#1:
代码实现
那个,
2
a
ba
bababa
0
这个自己造的数据过不了、
【模板】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;
代码实现
#include<cstdio> const int size=1e6+10; int n,a,ans; int q[size],h,t; char ch[size],cn[size]; int next[size][26],fail[size],v[size],sz; int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%s",ch); for(int j=0,k=0;;j++,k=next[k][a]){ if(!ch[j]){ v[k]++; break; } a=ch[j]-'a'; if(!next[k][a])next[k][a]=++sz; } } q[t++]=0; while(h<t){ a=q[h++]; for(int i=0,j;i<26;i++) if(next[a][i]){ j=fail[a]; while(j&&next[j][i]==0) j=fail[j]; fail[next[a][i]]=j!=a?next[j][i]:0; q[t++]=next[a][i]; } } scanf("%s",cn); for(int i=0,k=0;cn[i];i++){ a=cn[i]-'a'; while(k&&next[k][a]==0) k=fail[k]; k=next[k][a]; if(v[k]!=-1){ for(int j=k;j&&v[j]!=-1;j=fail[j]) ans+=v[j],v[j]=-1; } } printf("%d\n",ans); return 0; }
【模板】AC自动机(加强版)
题目描述
有NNN个由小写字母组成的模式串以及一个文本串TTT。每个模式串可能会在文本串中出现多次。你需要找出哪些模式串在文本串TTT中出现的次数最多。输入输出格式
输入格式:输入含多组数据。
每组数据的第一行为一个正整数NNN,表示共有NNN个模式串,1≤N≤1501 \leq N \leq 1501≤N≤150。
接下去NNN行,每行一个长度小于等于707070的模式串。下一行是一个长度小于等于10610^6106的文本串TTT。
输入结束标志为N=0N=0N=0。
输出格式:
对于每组数据,第一行输出模式串最多出现的次数,接下去若干行每行输出一个出现次数最多的模式串,按输入顺序排列。
输入输出样例
输入样例#1:2 aba bab ababababac 6 beta alpha haha delta dede tata dedeltalphahahahototatalpha 0
输出样例#1:
4 aba 2 alpha haha
代码实现
#include<cstdio> #include<cstring> inline int max_(int x,int y){return x>y?x:y;} const int maxn=1<<9-1; const int maxl=1<<21-1; const int size=1<<18-1; int n,a; int q[size],h,t; int tot[maxn],ans; char ch[maxn][maxn],cn[maxl]; int next[size][26],fail[size],to[size],sz; void find(int k){ int i,j; for(i=to[k],j=fail[k];j;j=fail[j]) i=to[j]?to[j]:i; to[k]=i; } int main(){ while(scanf("%d",&n),n){ ans=sz=h=t=0; memset(to,0,sizeof(to)); memset(tot,0,sizeof(tot)); memset(next,0,sizeof(next)); memset(fail,0,sizeof(fail)); for(int i=1;i<=n;i++){ scanf("%s",ch[i]); for(int j=0,k=0;;j++,k=next[k][a]){ if(!ch[i][j]){to[k]=i;break;} a=ch[i][j]-'a'; if(!next[k][a]) next[k][a]=++sz; } } q[t++]=0; while(h<t){ a=q[h++]; for(int i=0,j;i<26;i++) if(next[a][i]){ j=fail[a]; while(j&&next[j][i]==0) j=fail[j]; fail[next[a][i]]=j!=a?next[j][i]:0; q[t++]=next[a][i]; } } h=0; while(h<t) find(q[h++]); scanf("%s",cn); for(int i=0,k=0;cn[i];i++){ a=cn[i]-'a'; while(k&&next[k][a]==0) k=fail[k]; k=next[k][a]; if(to[k]) ans=max_(ans,++tot[to[k]]); } printf("%d\n",ans); for(int i=1;i<=n;i++) if(tot[i]==ans) puts(ch[i]); } return 0; }
那个,
2
a
ba
bababa
0
这个自己造的数据过不了、
相关文章推荐
- 杭电2896题 AC自动机模板题
- 洛谷 P3796 【模板】AC自动机(加强版)
- LA 4670 (AC自动机 模板题) Dominating Patterns
- AC自动机 模板 hdu 2896
- AC自动机 模板 【HDU2222】 Keywords Search
- AC自动机 模板
- AC自动机模板
- HDU 2222 - Keywords Search(AC自动机模板)
- AC自动机模板
- HDOJ-2222 AC自动机模板题..注意细节..
- 病毒侵袭(我的第二道AC自动机(模板进一步升级完善))
- ac自动机模板hdu2222
- cjoj P1435 - 【模板题 USACO】AC自动机 && 洛谷 P3796 【模板】AC自动机(加强版)
- hdu 2222 AC自动机模板题(指针版+数组版)
- AC自动机模板
- AC自动机模板
- HDU 3065 病毒侵袭持续中(AC自动机 数组模板)
- AC自动机 多模式串匹配 模板
- AC自动机算法模板
- HDU_2222 Keywords Search 【AC自动机模板题】【动态链表】