P3808 [模板]AC自动机(简单版)

[题目描述]

给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF=1e9+7;
inline LL read(){
register LL x=0,f=1;register char c=getchar();
while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
return f*x;
} const int MAXN=1e6+5;
const int MAXV=26; namespace ACzdj{
struct Trie{
int v[MAXV];
int fail,end;
}AC[MAXN];
int Ncnt;
inline void build(string s){
int cur=0,l=s.length();
for(int i=0;i<l;i++){
if(!AC[cur].v[s[i]-'a'])
AC[cur].v[s[i]-'a']=++Ncnt;
cur=AC[cur].v[s[i]-'a'];
}
AC[cur].end+=1;
}
inline void Get_fail(){
queue <int> q;
for(int i=0;i<26;i++)
if(AC[0].v[i]){
AC[AC[0].v[i]].fail=0;
q.push(AC[0].v[i]);
}
while(!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<26;i++){
if(AC[u].v[i]){
AC[AC[u].v[i]].fail=AC[AC[u].fail].v[i];
q.push(AC[u].v[i]);
}
else
AC[u].v[i]=AC[AC[u].fail].v[i];
}
}
}
inline int query(string s){
int res=0;
int l=s.length(),cur=0;
for(int i=0;i<l;i++){
cur=AC[cur].v[s[i]-'a'];
for(int t=cur;t&&AC[t].end!=-1;t=AC[t].fail){
res+=AC[t].end;
AC[t].end=-1;
}
}
return res;
}
}using namespace ACzdj; int n;
string s; int main(){
n=read();
for(int i=1;i<=n;i++){
cin>>s;
build(s);
}
AC[0].fail=0;
Get_fail();
cin>>s;
printf("%d\n",query(s));
}

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

[题目描述]

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

// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF=1e9+7;
inline LL read(){
register LL x=0,f=1;register char c=getchar();
while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
return f*x;
} const int MAXN=150000;
const int MAXM=155;
const int MAXV=26; struct Node{
int num,id;
friend bool operator < (Node a,Node b){
if(a.num==b.num) return a.id<b.id;
return a.num>b.num;
}
}ans[MAXM]; namespace ACzdj{
struct Trie{
int v[MAXV];
int fail,end;
}AC[MAXN];
int Ncnt;
inline void clear(int x){
for (register int i = 0; i < 26; ++i)
AC[x].v[i] = 0;
AC[x].fail=0,AC[x].end=0;
}
inline void build(const string& s,int id){
int cur=0,l=s.length();
for(int i=0;i<l;i++){
if(!AC[cur].v[s[i]-'a']){
AC[cur].v[s[i]-'a']=++Ncnt;
clear(Ncnt);
}
cur=AC[cur].v[s[i]-'a'];
}
AC[cur].end=id;
}
inline void Get_fail(){
queue<int> q;
for(int i=0;i<26;i++)
if(AC[0].v[i]){
AC[AC[0].v[i]].fail=0;
q.push(AC[0].v[i]);
}
while(!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<26;i++){
if(AC[u].v[i]){
AC[AC[u].v[i]].fail=AC[AC[u].fail].v[i];
q.push(AC[u].v[i]);
}
else
AC[u].v[i]=AC[AC[u].fail].v[i];
}
}
}
inline void query(const string& s){
int l=s.length(),cur=0;
for(int i=0;i<l;i++){
cur=AC[cur].v[s[i]-'a'];
for(int t=cur;t;t=AC[t].fail)
ans[AC[t].end].num++;
}
}
}using namespace ACzdj; int n;
string s[MAXM]; int main(){
// freopen("trie.in","r",stdin);
// freopen("trie.out", "w", stdout);
while(n = read()){
clear(Ncnt=0);
for(int i=1;i<=n;i++){
cin>>s[i];
ans[i].num=0,ans[i].id=i;
build(s[i],i);
}
AC[0].fail=0;
Get_fail();
cin>>s[0];
query(s[0]);
sort(ans+1,ans+n+1);
printf("%d\n",ans[1].num);
cout<<s[ans[1].id]<<endl;
for(int i=2;ans[i].num==ans[i-1].num&&i<=n;i++)
//printf("%s\n",s[ans[i].id]);
cout<<s[ans[i].id]<<endl;
}
}

AC自动机例题的更多相关文章

  1. AC自动机(模板+例题)

    首先要明白AC自动机是干什么的: AC自动机其实就是一种多模匹配算法,那么你可能会问什么叫做多模匹配算法.下面是我对多模匹配的理解,与多模与之对于的是单模,单模就是给你一个单词,然后给你一个字符串,问 ...

  2. AC自动机算法 && 例题

    参考链接: https://blog.csdn.net/bestsort/article/details/82947639#commentBox https://blog.csdn.net/niush ...

  3. AC自动机

    AC自动机,全称Aho-Corasick自动机.如果没记错的话好像就是前缀自动机. 其实AC自动机就是KMP上树的产物.理解了KMP,那AC自动机应该也是很好理解的. 与KMP类似,AC自动机也是扔一 ...

  4. [知识点]Trie树和AC自动机

    // 此博文为迁移而来,写于2015年5月27日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w1s8.html 1.前 ...

  5. 小结:ac自动机

    复杂度: 查找O(n),维护O(n) 概要: 应用了kmp的自匹配思想,在trie建图时维护一个fali指针,指向上一个匹配的点,这点是用bfs做到.匹配串的时候同样没匹配到就和kmp一样返回. 应用 ...

  6. AC自动机算法详解

    首先简要介绍一下AC自动机:Aho-Corasick automation,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法之一.一个常见的例子就是给出n个单词,再给出一段包含m个字符的文章, ...

  7. AC自动机讲解

    今天花了半天肝下AC自动机,总算啃下一块硬骨头,熬夜把博客赶出来.. 正如许多博客所说,AC自动机看似很难很妙,而事实上不难,但的确很妙.笼统地说,AC自动机=Trie+KMP,但是仅仅知道这个并没有 ...

  8. Aho-Corasick automaton(AC自动机)解析及其在算法竞赛中的典型应用举例

    摘要: 本文主要讲述了AC自动机的基本思想和实现原理,如何构造AC自动机,着重讲解AC自动机在算法竞赛中的一些典型应用. 什么是AC自动机? 如何构造一个AC自动机? AC自动机在算法竞赛中的典型应用 ...

  9. 算法笔记--字典树(trie 树)&& ac自动机 && 可持久化trie

    字典树 简介:字典树,又称单词查找树,Trie树,是一种树形结构,是哈希树的变种. 优点:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较. 性质:根节点不包含字符,除根节点外每一个 ...

随机推荐

  1. 05-nginx定时任务完成日志切割

    目标:每天晚上凌晨一点钟左右把昨天的任务给它切掉,把昨天的日志给它改个名存起来,根据昨天的时间给它改个名存起来,所以要根据日期生成文件名. 也许你不会写bash脚本,但是老师带着你一步一步地来. sh ...

  2. map两种插入方法解析(insert() 与 下标[]操作)

    insert 含义是: 如果key存在,则插入失败,如果key不存在,就创建这个key-value. 实例: map.insert((key, value)) 利用下标操作的含义是: 如果这个key存 ...

  3. c语言入门教程

    https://www.youtube.com/playlist?list=PLY_qIufNHc293YnIjVeEwNDuqGo8y2Emx 感觉这个教程不错

  4. RocketMq2

  5. Luogu 1379 八数码难题

    吐槽:此题就是一点一点卡过去的 警告: 1.千万不能用dfs搜这种东西(dfs需要遍历所有状态才能找到最优解), 分分钟爆炸 2.写结构体的时候要综合判断&的加和不加 Code: // luo ...

  6. lnmp+laravel部署到服务器出现 "GET / HTTP/1.1" 500 5

    lnmp一键安装包直接下载安装,就可以了,在此不多说. 虚拟机配置给个参考(lnmp安装包) server { listen 80; #listen [::]:80; server_name www. ...

  7. [GO]map做函数参数

    package main import "fmt" func test(m map[int]string) { delete(m, ) } func main() { m := m ...

  8. VUE实战项目-数据转换之道

    前言 公司的这个项目从去年底启动.至今经历winform版本与当前的VUE两个版本,前后经历不足3个月的时间.从纯技术角度来看,推进速度都很优异.究其原因,大抵我们都是喜欢“偷懒”的程序员,把能封装. ...

  9. C#获取文件的Content-Type(MIME Type)的方法

    使用静态类MimeMapping(需要.NET Framework 4.5及以后的支持) string fileName = "D:\myfile.txt"; var conten ...

  10. 前端mock利器:randomjson

    randomjson的应用场景 前后端分离时,前端根据后端提供的数据模型模拟后端请求.如果数据写死,每次返回的都一样,这个时候randomjson就能派上用场了.在前端规定数据类型,每次用random ...