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

记录当前\(cnt\)是第几个"星"。记录第几个串是对应着第几个星。

这里补充一点对于\(AC\)自动机的理解。可能一直有个问题我没有想明白,就是打标记的点只有一个,然而匹配时,假若一个分支包括了另一个不同的分支该怎么办。实际上,我们可以在匹配的时候使用\(fail\)数组进行类似链式前向星的遍历,从而遍历到那个打标记的地方。那么问题来了,怎么保证链式前向星会遍历到那个打了标记的节点呢?答案就在\(gen\_fail\)的玄机里。\(gen\_fail\)时,由于是找和已经匹配部分相同的后缀,所以指向的节点它到\(0\)的长度会越来越小。显然那个有标记点的串是相较其它包括它自己的串中最短的,那么一定会被这个链式前向星遍历到。

上代码

#include<bits/stdc++.h>

using namespace std;
#define RP(t,a,b) for(register int t=(a),edd=(b);t<=edd;++t)
#define DRP(t,a,b) for(register int t=(a),edd=(b);t>=edd;--t)
#define ERP(t,a) for(register int t=head[a];t;t=e[t].nx)
#define Max(a,b) ((a)<(b)?(b):(a))
#define Min(a,b) ((a)<(b)?(a):(b))
#define midd register int mid=(l+r)>>1
#define TMP template < class ccf > TMP inline ccf qr(ccf b){
char c=getchar();
int q=1;
ccf x=0;
while(c<48||c>57)
q=c==45?-1:q,c=getchar();
while(c>=48&&c<=57)
x=x*10+c-48,c=getchar();
return q==-1?-x:x;
}
const int maxn=155;
struct AC{
int fail;
int son[27];
int cnt;
inline int& operator [](int x){
return son[x];
}
inline int& operator [](char x){
return son[x-'a'+1];
}
}ac[maxn*70]; string x[maxn];
int toac[maxn];
int acnt[maxn];
int macnt[maxn];
int act;
int prcnt;
int n; inline int build(string p,int len){
register int now=0;
RP(t,0,len-1){
if(!ac[now][p[t]])
ac[now][p[t]]=++act;
now=ac[now][p[t]];
}
if(!ac[now].cnt)
ac[now].cnt=++prcnt;
return ac[now].cnt;
} queue < int > q;
inline void gen(){
RP(t,1,26){
if(ac[0][t])
q.push(ac[0][t]);
}
while(!q.empty()){
register int now=q.front();
q.pop();
RP(t,1,26){
if(ac[now][t])
ac[ac[now][t]].fail=ac[ac[now].fail][t],q.push(ac[now][t]);
else
ac[now][t]=ac[ac[now].fail][t];
}
}
} inline void match(string p,int len){
register int now=0;
RP(t,0,len-1){
now=ac[now][p[t]];
for(register int i=now;i;i=ac[i].fail){
if(ac[i].cnt)
macnt[ac[i].cnt]++;
}
}
} int main(){
#ifndef ONLINE_JUDGE
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
#endif
while( (n=qr(1)) ){
memset(ac,0,sizeof ac);
memset(macnt,0,sizeof macnt);
act=prcnt=0;
RP(t,1,n){
cin>>x[t];
toac[t]=build(x[t],x[t].length());
}
gen();
cin>>x[0];
match(x[0],x[0].length());
register int ans=0;
RP(t,1,prcnt)
ans=Max(ans,macnt[t]);
cout<<ans<<endl;
RP(t,1,n)
if(macnt[toac[t]]==ans)
cout<<x[t]<<endl;
}
return 0;
}

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

  1. 【题解】GREWords(AC自动机)

    [题解]GREWords(AC自动机) SP9941 GRE - GRE Words 题目大意: 给定一个由字符串构成的序列,不同位置的字符串有自己权值.现在让你选出一个子序列,使得在这个子序列中,前 ...

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

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

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

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

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

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

  5. 模板 AC自动机

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

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

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

  7. [模板][P3796]AC自动机(加强版)

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

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

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

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

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

  10. 模板—AC自动机

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

随机推荐

  1. Springboot如何优雅的解决ajax+自定义headers的跨域请求

    1.什么是跨域 由于浏览器同源策略(同源策略,它是由Netscape提出的一个著名的安全策略.现在所有支持JavaScript 的浏览器都会使用这个策略.所谓同源是指,域名,协议,端口相同.),凡是发 ...

  2. delphi如何把一个整数转化为4个十六进制字节

    var   s:string;   len:Integer;   AData:TBytes; begin        s:=IntToHex(149259,6);//返回6位字符串     len  ...

  3. mysql之日期函数

    写在前面 mysql的学习,断断续续,今天就接着学习mysql的日期操作吧. 系列文章 mysql之创建数据库,创建数据表 mysql之select,insert,delete,update mysq ...

  4. UVA 133“The Dole Queue”(循环报数处理技巧)

    •参考资料 [1]:紫书P82 •题意(by紫书) 按照被选中的次序输出这 n 个人的编号: 如果A和B选中的是同一个人,输出一个这个人的编号: 输出格式:输出的每个编号占3个字节,不够3个字节在前面 ...

  5. MyBatis-Invalid bound statement (not found)-问题处理

    最近把工程改为Hibernate和MyBatis并存,并存只要注意两点即可: 1.使用同一个dataSource 2.事物交给Hibernate进行管理(Hibernate4+)  Hibernate ...

  6. 【温故知新】——HTML5重要知识点复习

    前言:本文是自己在学习课程中的课程笔记,这里用来温故知新的,并非本人原创. 一.HTML5新特性 —— 十个新特性:凌乱 (1)新的语义标签 (2)增强型表单(表单2.0) (3)音频和视频 (4)C ...

  7. js 简单getByClass得封装

    function getByClass(oParent,sClass){ var elems = oParent.getElementsByTagName("*"); var ar ...

  8. vue 监听 watch 使用

    1.api https://cn.vuejs.org/v2/api/#watch 有2个配置: (1)深度 watcher deep: true(2)该回调将会在侦听开始之后被立即调用 immedia ...

  9. fiddler不能监听 localhost和 127.0.0.1的问题 .

    localhost/127.0.0.1的请求不会通过任何代理发送,fiddler也就无法截获. 解决方案 用 http://localhost. (locahost紧跟一个点号) 用 http://1 ...

  10. win10+vs2017+asp.net MVC5+EF6+mysql 闪退问题,解决方法

    1.安装 mysql-for-visualstudio-2.0.5.msi 2.安装 mysql-connector-net-6.10.7.msi 3.在VS2017 右键选中项目,管理NuGet程序 ...