传送门

AC自动机的模板

简单的理解就是字典树上的KMP

注意数组不要开太大

不然每次memset耗时太多

有一个小优化

每次走 fail 边找匹配时只有一些会更新答案

那么就可以把没用的fail边压缩掉

设 g[x] 表示从 x 点一直走 fail 边,走到的第一个有结束标记的点

那么找匹配时就只有要 g 边

然后就是模板了

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
const int N=5e4+;
int len,n;
char s[];
inline void read_s()//文本串比较大,可以用快读加速
{
char ch=getchar(); len=;
while(ch<'a'||ch>'z') ch=getchar();
while(ch>='a'&&ch<='z')
{
s[++len]=ch;
ch=getchar();
}
}
int c[N][],pd[N],fail[N],g[N],cnt;
char a[][]; int l[];
inline void clr()//清空AC自动机
{
memset(c,,sizeof(c));
memset(pd,,sizeof(pd));
memset(fail,,sizeof(fail));
memset(g,,sizeof(g));
cnt=;
}
inline void ins(int num)//插入单词到自动机(跟字典树没区别)
{
int u=;
for(int i=;i<l[num];i++)
{
int v=a[num][i]-'a'+;
if(!c[u][v]) c[u][v]=++cnt;
u=c[u][v];
}
pd[u]=num;
}
queue <int> q;
inline void pre()//预处理fail和g
{
for(int i=;i<=;i++)
if(c[][i]) q.push(c[][i]);
while(!q.empty())
{
int u=q.front(); q.pop();
for(int i=;i<=;i++)
{
int v=c[u][i];
if(!v) c[u][i]=c[fail[u]][i];//失配了直接走失配边
else
{
fail[v]=c[fail[u]][i];
g[v]= pd[fail[v]] ? fail[v] : g[fail[v]];//处理g
q.push(v);
}
}
}
}
int mx,ans[];
inline void query()//AC自动机匹配(好像跟字典树也没什么区别)
{
memset(ans,,sizeof(ans));
int u=;
for(int i=;i<=len;i++)
{
u=c[u][s[i]-'a'+];
if(pd[u]) ans[pd[u]]++;
for(int j=g[u];j;j=g[j])
ans[pd[j]]++;
//计算匹配
}
mx=;
for(int i=;i<=n;i++)
mx=max(mx,ans[i]);
cout<<mx<<endl;
for(int i=;i<=n;i++)
if(ans[i]==mx)
printf("%s\n",a[i]);
}
int main()
{
while()
{
scanf("%d",&n); if(!n) break;
clr();
for(int i=;i<=n;i++)
{
scanf("%s",a[i]);
l[i]=strlen(a[i]);
ins(i);
}
pre();
read_s();
query();
}
return ;
}

P3796 【模板】AC自动机的更多相关文章

  1. luoguP3808[模板]AC自动机(简单版)

    传送门 ac自动机模板题,裸的多串匹配 代码: #include<cstdio> #include<iostream> #include<algorithm> #i ...

  2. luoguP3796[模板]AC自动机(加强版)

    传送门 ac自动机模板,可能我写的ac自动机是有点问题的,所以跑的有些慢 暴力跳fail统计 代码: #include<cstdio> #include<iostream> # ...

  3. 算法模板——AC自动机

    实现功能——输入N,M,提供一个共计N个单词的词典,然后在最后输入的M个字符串中进行多串匹配(关于AC自动机算法,此处不再赘述,详见:Aho-Corasick 多模式匹配算法.AC自动机详解.考虑到有 ...

  4. 模板 AC自动机

    题目描述 有$N$ 个由小写字母组成的模式串以及一个文本串$T$ .每个模式串可能会在文本串中出现多次.你需要找出哪些模式串在文本串$T$ 中出现的次数最多. 输入输出格式 输入格式: 输入含多组数据 ...

  5. 算法竞赛模板 AC自动机

    AC自动机基本操作 (1) 在AC自动机中,我们首先将每一个模式串插入到Trie树中去,建立一棵Trie树,然后构建fail指针. (2) fail指针,是穿插在Trie树中各个结点之间的指针,顾名思 ...

  6. 洛谷.3808/3796.[模板]AC自动机

    题目链接:简单版,增强版 简单版: #include <cstdio> #include <cstring> const int N=1e6+5,S=26; char s[N] ...

  7. 模板—AC自动机

    #include<iostream> #include<cstdio> #include<cstring> using namespace std; struct ...

  8. 模板——AC自动机

    传送门:QAQQAQ 定义nxt[u]=v表示从u开始不断沿着失配边跳到的第一个是标记点的端点v,那么我们再匹配时沿着last跳,每跳到一个last,它就一定对应一个模式串,所以效率是非常高的. 和K ...

  9. AC自动机例题

    P3808 [模板]AC自动机(简单版) [题目描述] 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. #include<bits/stdc++.h> using name ...

  10. 「kuangbin带你飞」专题十七 AC自动机

    layout: post title: 「kuangbin带你飞」专题十七 AC自动机 author: "luowentaoaa" catalog: true tags: - ku ...

随机推荐

  1. Android排错: has leaked window com.android.internal.policy.impl.PhoneWindow$ that was originally added here

    异常场景: 经常在应用中需要处理一些耗时的工作,诸如读取大文件.访问网络资源等.为了避免因程序假死而带来的糟糕用户体验,通常我们可以通过线程+Handler或者Android提供的AsyncTask来 ...

  2. B和strong以及i和em的区别(转)

    B和strong以及i和em的区别 (2013-12-31 13:58:35) 标签: b strong i em 搜索引擎 分类: 网页制作 一直以来都以为B和strong以及i和em是相同的效果, ...

  3. SpringBoot04 日志框架之Logback

    1 日志框架选择 日志门面:SLF4J 日志实现:Logback 2 实现控制台的日志打印输出01 2.1 在需要实现日志信息打印的类中实例化Logger对象 坑01:springBoot项目默认使用 ...

  4. STM32 C++编程 004 Adc (数模转换)类

    使用 C++ 语言给 STM32 编写一个 Adc 类 我使用的STM32芯片:STM32F103ZET6 我们使用的STM32库版本:V3.5.0 注意: 想学习本套 STM32 C++编程 的专栏 ...

  5. 高性能MySQL笔记-第5章Indexing for High Performance-001B-Tree indexes(B+Tree)

    一. 1.什么是B-Tree indexes? The general idea of a B-Tree is that all the values are stored in order, and ...

  6. Luogu 3193 [HNOI2008]GT考试

    BZOJ1009 妙! 推荐这篇题解: https://www.luogu.org/blog/Edgration/solution-p3193 考虑设计dp,设$f_{i, j}$表示长串匹配到i,短 ...

  7. then方法

    sendSMS(phoneNo).then(function(data) { var msg = (data && data['msg']) ? data['msg'] : '验证码已 ...

  8. Python程序设计1——基础知识

    1 Python脚本设计简介 1.1 输出"Hello World" 和一般的语言一样,运行python程序有两种方式,一种是GUI交互式命令,一种是通过脚本文件,前者适合小型简单 ...

  9. java全栈day01-01

    一 常用dos命令d:dir:列出当前目录下的文件以及文件夹md 创建目录rd 删除目录cd 进入指定的目录cd\ 返回根目录del a.txtdel *.txt 删除所有文件exit :退出dos ...

  10. Java 深入变量和封装思想小结

    1.变量的分类和初始值 成员变量:有初始值 局部变量:没有初始值 2.类字段 static :存在于方法区里面 实例变量(实例字段):存在于堆里面 局部变量:存在于栈里面 方法的覆盖: 子类覆盖父类: ...