洛谷 P3796 【模板】AC自动机(加强版)(AC自动机)
题目链接:https://www.luogu.com.cn/problem/P3796
AC自动机:复杂度$O( (N+M)\times L )$,N为模式串个数,L为平均长度,M为文章长度。
insert:
构造一个trie,然后标记一下每一个模式串的最后一个,即$vis$。
get_fail:
进行在trie上进行BFS,第一层点的失配指针指向根节点;之后的一个节点失配指针指向/他父亲的失配指针/指向的节点中/的儿子具有相同节点的位置。
这里有一个小优化:fail是用来寻找失配时走到的位置的,走一个点fail的他的ch[i]一定是没有的。那么可以用这些ch指针直接指向它的fail的ch[i],可以发现这样操作之后,每个点的ch[i]直接指向了原本沿着失配边不停走的最终结果,这样的话,匹配时每次用ch指针的对象即可,不用一直沿fail边走看看这个点有没有ch[i]了。
query:
向下一层循环求解,直到fail不能走了,注意如果j不是终点,那么即ans[0]++,但最终不影响结果,因为统计时从1开始...
AC代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int N=+;
const int maxn=;
int fail[N],ch[N][],vis[N];
int ans[N];
string s[maxn];
int cnt;
void insert(string s,int v){
int u=;
int len=s.length();
for(int i=;i<len;i++){
int id=s[i]-'a';
if(!ch[u][id]) ch[u][id]=++cnt;
u=ch[u][id];
}
vis[u]=v;
}
void get_fail(){
int now=;
queue<int> q;
for(int i=;i<;i++){
if(ch[now][i]){
q.push(ch[now][i]);
fail[ch[now][i]]=now;
}
}
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=;i<;i++){
int v=ch[u][i];
if(v) fail[v]=ch[fail[u]][i],q.push(v);
else ch[u][i]=ch[fail[u]][i];//you hua
}
}
}
void query(string s){
int now=;
int len=s.length();
for(int i=;i<len;i++){
now=ch[now][s[i]-'a'];
for(int j=now;j;j=fail[j]) ans[vis[j]]++;
}
}
int main(){
int n;
while(scanf("%d",&n)){
memset(vis,,sizeof(vis));
memset(ans,,sizeof(ans));
memset(ch,,sizeof(ch));
memset(fail,,sizeof(fail));
if(n==) break;
for(int i=;i<=n;i++){
cin>>s[i];
insert(s[i],i);
}
get_fail();
string str;
cin>>str;
query(str);
int maxx=;
for(int i=;i<=n;i++) maxx=max(maxx,ans[i]);
printf("%d\n",maxx);
for(int i=;i<=n;i++) if(ans[i]==maxx) cout<<s[i]<<endl;
}
return ;
}
AC代码
洛谷 P3796 【模板】AC自动机(加强版)(AC自动机)的更多相关文章
- 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)
To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...
- 洛谷P1120 小木棍 [数据加强版](搜索)
洛谷P1120 小木棍 [数据加强版] 搜索+剪枝 [剪枝操作]:若某组拼接不成立,且此时 已拼接的长度为0 或 当前已拼接的长度与刚才枚举的长度之和为最终枚举的答案时,则可直接跳出循环.因为此时继续 ...
- 洛谷P3796 【模板】AC自动机(加强版)(AC自动机)
洛谷题目传送门 先膜一发yyb巨佬 orz 想学ac自动机的话,推荐一下yyb巨佬的博客,本蒟蒻也是从那里开始学的. 思路分析 裸的AC自动机,这里就不讲了.主要是这题太卡时了,尽管时限放的很大了.. ...
- 洛谷-P5357-【模板】AC自动机(二次加强版)
题目传送门 -------------------------------------- 过年在家无聊补一下这周做的几道AC自动机的模板题 sol:AC自动机,还是要解决跳fail边产生的重复访问,但 ...
- 洛谷-P3796-【模板】AC自动机(加强版)
题目传送门 -------------------------------------- 过年在家无聊补一下这周做的几道AC自动机的模板题 sol:AC自动机,在fail边的基础上再加一个last边, ...
- 【AC自动机】洛谷三道模板题
[题目链接] https://www.luogu.org/problem/P3808 [题意] 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. [题解] 不再介绍基础知识了,就是裸的模 ...
- 【洛谷 P2444】 [POI2000]病毒(AC自动机)
题目链接 这么多字符串,肯定是自动机啦. 先建出AC自动机,然后怎么表示一个安全代码没有病毒代码呢? 就是存在一条路径不经过有病毒代码段结尾的节点呗. 所以呢?有环啊!dfs一下救星了. #inclu ...
- 洛谷P3375 [模板]KMP字符串匹配
To 洛谷.3375 KMP字符串匹配 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.如果 ...
- LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)
为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...
- 洛谷.1919.[模板]A*B Problem升级版(FFT)
题目链接:洛谷.BZOJ2179 //将乘数拆成 a0*10^n + a1*10^(n-1) + ... + a_n-1的形式 //可以发现多项式乘法就模拟了竖式乘法 所以用FFT即可 注意处理进位 ...
随机推荐
- #《Essential C++》读书笔记# 第三章 泛型编程风格
基础知识 array与vector是连续存储空间,可以用指针的算术运算实现对容器的访问.list也是一个容器,不同的是,list的元素以一组指针相互链接(linked):前向(forward)指针指向 ...
- redis主从同步,总是显示master_link_status:down的解决方法
小编使用的redis的版本号是5.0.5,可能会略有不同,例如redis.conf配置文件中,没有slaveof这一项配置 使用命令配置主从复制 今天在使用命令slaveof或者是replicaof命 ...
- CentOS7.6安装MySQL8.0(图文详细篇)
目录 一.安装前准备 二.安装MySQL 三.设置远程登录 四.安装问题解决 五.设置MySQL开机自启 一.安装前准备 1.在官网下载MySQL安装包(注意下载的安装包类型) 2.查看是否安装ma ...
- 回炉重造之重读Windows核心编程-006-线程
线程也是有两部分组成的: 线程的内核对象,操作系统用来管理线程和统计线程信息的地方. 线程堆栈,用于维护现场在执行代码的时候用到的所有函数参数和局部变量. 进程是线程的容器,如果进程中有一个以上的线程 ...
- java的jdbc连接数据库,读取表中数据
连接数据库操作步骤如下 架包 jar 建表 源码解析 1:架包 jar根据自己本版本选择正确jar包,本例采用maven 管理局,在pom.xml 中添加如下代码,自动下载架包 <depende ...
- MongoDB3.4版本新增特性
先说明一下mongod和mongos的含义:mongod是MongoDB系统的主要后台进程,它处理数据请求.管理数据访问和执行后台管理操作:该命令的命令行选项主要用于测试,在场景操作中,使用配置文件选 ...
- mysql第八课
开启事务: START TRANSACTION; 提交事务: COMMIT; 回滚事务: ROLLBACK; 事务的概念:原子性,一致性,隔离性,持久性 READ UNCOMMITTED(读了未提交) ...
- 腾讯qlv视频转为MP4格式工具
本文解决上一篇<优酷爱奇艺视频转换为MP4格式工具>留下的腾讯视频qlv转MP4格式问题,教程都是一步步亲手操作的,每一步都有配图.希望各位老板多转发分享,谢谢! 解压软件.(建议关闭所有 ...
- awk - 提取包含某个关键字的段落
前提 AWK是一种处理文本文件的语言,是一个强大的文本分析工具. 本文将使用命令awk将具有某个关键字的段落提取出来. 准备数据 "Finalizer" #3 daemon pri ...
- sqlserver with 递归用法
DECLARE @companyid TABLE ( [Id] [int] ); with cte as( union all select a.Id from [base].[Company] a, ...