P3796 【模板】AC自动机(加强版)

时间:2022-08-30 23:32:10

P3796 【模板】AC自动机(加强版)

https://www.luogu.org/problemnew/show/P3796

题目描述

有NN个由小写字母组成的模式串以及一个文本串TT。每个模式串可能会在文本串中出现多次。你需要找出哪些模式串在文本串TT中出现的次数最多。

输入输出格式

输入格式:

输入含多组数据。

每组数据的第一行为一个正整数NN,表示共有NN个模式串,1 \leq N \leq 1501≤N≤150。

接下去NN行,每行一个长度小于等于7070的模式串。下一行是一个长度小于等于10^6106的文本串TT。

输入结束标志为N=0N=0。

输出格式:

对于每组数据,第一行输出模式串最多出现的次数,接下去若干行每行输出一个出现次数最多的模式串,按输入顺序排列。

输入输出样例

输入样例#1:
2
aba
bab
ababababac
6
beta
alpha
haha
delta
dede
tata
dedeltalphahahahototatalpha
0
输出样例#1:
4
aba
2
alpha
haha
 #include<bits/stdc++.h>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define sqr(x) ((x)*(x))
#define maxn 1000005
typedef long long ll;
typedef unsigned long long ull;
const ull MOD=;
/*#ifndef ONLINE_JUDGE
freopen("1.txt","r",stdin);
#endif */ struct tree{
int fail;
int vis[];
int num;
}ac[]; int cnt=; struct ANS{
int num,pos;
bool operator<(const ANS &b){
if(num==b.num) return pos<b.pos;
return num>b.num;
}
}ans[]; void Clear(int x){
memset(ac[x].vis,,sizeof(ac[].vis));
ac[x].num=ac[x].fail=;
} void build(string s,int flag){///建trie树
int len=s.length();
int now=;
for(int i=;i<len;i++){
if(ac[now].vis[s[i]-'a']==){
ac[now].vis[s[i]-'a']=++cnt;
Clear(cnt);
}
now=ac[now].vis[s[i]-'a'];
}
ac[now].num=flag;
} void get_fail(){///构建成trie图
queue<int>Q;
ac[].fail=;
for(int i=;i<;i++){
if(ac[].vis[i]){
ac[ac[].vis[i]].fail=;
Q.push(ac[].vis[i]);
}
}
while(!Q.empty()){
int u=Q.front();
Q.pop();
for(int i=;i<;i++){
if(ac[u].vis[i]){
ac[ac[u].vis[i]].fail=ac[ac[u].fail].vis[i];
Q.push(ac[u].vis[i]);
}
else{
ac[u].vis[i]=ac[ac[u].fail].vis[i];///如果当前结点不存在,就指向父亲结点的fail指向的结点的子结点
}
}
}
} void ac_query(string s){
int len=s.length();
int now=;
for(int i=;i<len;i++){
now=ac[now].vis[s[i]-'a'];
for(int t=now;t&&ac[t].num!=-;t=ac[t].fail){
ans[ac[t].num].num++;
}
}
} string s[]; int main(){
#ifndef ONLINE_JUDGE
freopen("1.txt","r",stdin);
#endif
std::ios::sync_with_stdio(false);
int n;
while(cin>>n){
if(!n) break;
Clear();
for(int i=;i<=n;i++){
cin>>s[i];
build(s[i],i);
ans[i].num=;
ans[i].pos=i;
}
get_fail();
cin>>s[];
ac_query(s[]);
sort(ans+,ans+n+);
cout<<ans[].num<<endl;
cout<<s[ans[].pos]<<endl;
for(int i=;i<=n;i++){
if(ans[i].num==ans[i-].num){
cout<<s[ans[i].pos]<<endl;
}
else{
break;
}
}
}
}

P3796 【模板】AC自动机(加强版)的更多相关文章

  1. luoguP3796&lbrack;模板&rsqb;AC自动机(加强版)

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

  2. luoguP3808&lbrack;模板&rsqb;AC自动机(简单版)

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

  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. &lbrack;模板&rsqb;&lbrack;P3796&rsqb;AC自动机&lpar;加强版&rpar;

    Description: 输出有哪些模式串在文本串中出现次数最多,这个次数是多少 Hint: 多组数据,$ len_{文本串}<=10^6,\sum len_{模式串} <= 70*150 ...

  7. 【模板】AC自动机加强版

    题目大意:给定 N 个模式串和一个文本串,求每个模式串在文本串中出现的次数. 题解:文本串在自动机上匹配的过程中,记录下自动机上每一个状态被访问的次数.对于访问到的节点 i,则状态 i 的后缀中存在的 ...

  8. 洛谷&period;3808&sol;3796&period;&lbrack;模板&rsqb;AC自动机

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

  9. 模板—AC自动机

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

  10. 模板——AC自动机

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

随机推荐

  1. &lbrack;问题2014A02&rsqb; 解答三(降阶公式法)

    [问题2014A02] 解答三(降阶公式法) 将矩阵 \(A\) 写成如下形式: \[A=\begin{pmatrix} -2a_1 & 0 & \cdots & 0 &amp ...

  2. windows下如何使用makefile编译

    1. 编写makefile. 2. 使用nmake进行编译, vs2010或者其他都是用nmake进行编译的,将bin目录添加到path环境变量中 先执行vcvars32.bat 再执行nmake

  3. for循环语句之棋盘放粮食、百鸡百钱、纸张的折叠问题

    1.棋盘放粮食 ; ; i < ; i++) { ; ; j <= i; j++) { x = x * ; } lszl = lszl + x; } double zl = lszl * ...

  4. IIC接口下的24C02 驱动分析

    本节来学习IIC接口下的24C02 驱动分析,本节学完后,再来学习Linux下如何使用IIC操作24C02 1.I2C通信介绍 它是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据,是一个多 ...

  5. VS2015中配置Eigen

    Eigen非常方便矩阵操作,当然它的功能不止如此.矩阵操作在算法研究过程中,非常重要,例如在图像处理中二维高斯拟合求取光斑中心时使用Eigen提供的矩阵算法,差不多十来行代码即可实现. 1)下载Eig ...

  6. android&lowbar;双击退出

    /** * 设置高速双击退出程序 */ @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // TODO Auto-g ...

  7. Java面试总结(面试流程及核心面试题)

    Java面试流程及核心面试题 面试整体流程 1.1 简单的自我介绍      我是xxxx,工作xxx年.我先后在xxxx公司.yyyy公司工作.先后做个xxxx项目.yyyy项目. 1.2 你简单介 ...

  8. 中国将有可能在全球化的背景下收获新的人口红利:3星&vert;《&lt&semi;财经&gt&semi;2019:预测与战略》

    <财经>2019 :预测与战略 <财经>杂志的年刊.内容是针对2019年的预测分析.我认为<财经>的调查报告比较有深度,分析则不是我爱看的类型. 总体评价3星,有参 ...

  9. DevExpress VCL for Delphi 各版本收集下载

    更多VCL组件请到:http://maxwoods.400gb.com/u/758954/1974711 DevExpress VCL 5.7:http://www.ctdisk.com/file/7 ...

  10. Data Guard 主备库角色转换

    1. switchover操作 1.1 备库先关闭实时日志应用 standby>alter database recover managed standby database cancel; 1 ...