洛谷 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即可 注意处理进位 ...
随机推荐
- Java之GUI编程
GUI编程 组建 窗口 弹窗 面板 文本框 列表框 按钮 图片 监听事件 鼠标 键盘事件 破解工具 1.简介 GUI的核心技术:Swing AWT 为什么不流行? 界面不美观. 需要jre环境.(没必 ...
- Linux学习记录(一):常用命令
此篇文章为博主在Linux学习过程中的一些记录,记录在此方便查阅. 常用命令总结 ls 显示目录内容 (list directory contents) ls 不显示隐藏的文件和子目录 ls -a 显 ...
- 贪心训练均分纸牌Noip2002
题目链接:https://www.luogu.com.cn/problem/P1031 题目描述 有N堆纸牌,编号分别为 1,2,…,N.每堆上有若干张,但纸牌总数必为N的倍数.可以在任一堆上取若干张 ...
- MATLAB应用专题part1-电力电子仿真技术
士不可以不弘毅,任重而道远.仁以为己任,不亦重乎?死而后已,不亦远乎? --曾参 C语言系列需要过一段时间才能更新了.这些天学习C语言我感觉有点崩溃了,所以我先开另外一个专题-matlab应用专题. ...
- 【第三篇】C#调用lua文件
获取一个全局基本数据类型 使用LuaEnv.Global.Get<T>("name")就可以 var str = luaEnv.Global.Get<string ...
- EasyUI笔记(五)表单
本系列只列出一些常用的属性.事件或方法,具体完整知识请查看API文档 Form(表单) 创建一个简单的HTML表单.构建一个包含id.action和method值的表单元素. <form id= ...
- 有关配置网站时安装ZipArache的方法。
在配置网站初始化过程中,发现ZipArache需要启动,上网搜索了一番,发现安装ZipArache的步骤十分繁琐. 换一种思路,ZipArache作为PHP的拓展类,其名字首部有ZIP字样,那么可否直 ...
- opencv —— 同时识别三种颜色
要点: 1.识别一种颜色 minH = ; //色相 maxH = ; minS = ; //饱和度 maxS = ; minV = ; // inRange(原图像, 最小值的范围, 最大值的范围, ...
- 关于所学,及JNI问题
上周每天学习Java两个小时,随后两个小时里对教材上的例子进行验证,学会了如何使用Javac对文件进行终端编译,输出,但由于所下载的 jdk版本问题出现了JNI问题,正在尝试解决.并学会了如何使用ec ...
- centos-python3.5安装
python版本:Python-3.5.5.tgz tar -xvf Python-3.5.5.tgz cp Python-3.5.5 /usr/local cd /usr/local/Python- ...