AC自动机例题
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自动机例题的更多相关文章
- AC自动机(模板+例题)
首先要明白AC自动机是干什么的: AC自动机其实就是一种多模匹配算法,那么你可能会问什么叫做多模匹配算法.下面是我对多模匹配的理解,与多模与之对于的是单模,单模就是给你一个单词,然后给你一个字符串,问 ...
- AC自动机算法 && 例题
参考链接: https://blog.csdn.net/bestsort/article/details/82947639#commentBox https://blog.csdn.net/niush ...
- AC自动机
AC自动机,全称Aho-Corasick自动机.如果没记错的话好像就是前缀自动机. 其实AC自动机就是KMP上树的产物.理解了KMP,那AC自动机应该也是很好理解的. 与KMP类似,AC自动机也是扔一 ...
- [知识点]Trie树和AC自动机
// 此博文为迁移而来,写于2015年5月27日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w1s8.html 1.前 ...
- 小结:ac自动机
复杂度: 查找O(n),维护O(n) 概要: 应用了kmp的自匹配思想,在trie建图时维护一个fali指针,指向上一个匹配的点,这点是用bfs做到.匹配串的时候同样没匹配到就和kmp一样返回. 应用 ...
- AC自动机算法详解
首先简要介绍一下AC自动机:Aho-Corasick automation,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法之一.一个常见的例子就是给出n个单词,再给出一段包含m个字符的文章, ...
- AC自动机讲解
今天花了半天肝下AC自动机,总算啃下一块硬骨头,熬夜把博客赶出来.. 正如许多博客所说,AC自动机看似很难很妙,而事实上不难,但的确很妙.笼统地说,AC自动机=Trie+KMP,但是仅仅知道这个并没有 ...
- Aho-Corasick automaton(AC自动机)解析及其在算法竞赛中的典型应用举例
摘要: 本文主要讲述了AC自动机的基本思想和实现原理,如何构造AC自动机,着重讲解AC自动机在算法竞赛中的一些典型应用. 什么是AC自动机? 如何构造一个AC自动机? AC自动机在算法竞赛中的典型应用 ...
- 算法笔记--字典树(trie 树)&& ac自动机 && 可持久化trie
字典树 简介:字典树,又称单词查找树,Trie树,是一种树形结构,是哈希树的变种. 优点:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较. 性质:根节点不包含字符,除根节点外每一个 ...
随机推荐
- 张超超OC基础回顾02_成员变量(属性),局部变量,全局变量的区别
成员变量: 写在类声明的大括号中的变量, 我们称之为 成员变量(属性, 实例变量) 成员变量只能通过对象来访问 注意: 成员变量不能离开类, 离开类之后就不是成员变量 成员变量不能在定义的同时进行初始 ...
- 嵌入式Qt开发环境的搭建详解
一.嵌入式Qt开发环境的搭建前奏 1.下载arm-linux-gcc-4.4.3-20100728.tar.gz 2.下载qt-everywhere-opensource-src-4.8.5.tar. ...
- 数字图像处理实验(8):PROJECT 04-04,Highpass Filtering Using a Lowpass Image 标签: 图像处理MATLAB 2017-05-25 0
实验要求: 高通滤波器可以通过1减去低通滤波器的传递函数得到. 使用公式 计算可以的得到 . 实验代码: % PROJECT 04-04 Highpass Filtering Using a Lowp ...
- setnx()
setnx(key,value):当指定的key不存在时,为你设置指定的值
- keydown、input 和 keyup 事件
keydown.keyup 属于键盘事件,input 属于文本事件. keydown:当用户按下键盘上的任意按键时触发,如果按住不放,会重复触发此事件. keyup:当用户释放键盘上的按键时触发. i ...
- Nginx配置 简单写了个
#user nobody;worker_processes 1; #error_log logs/error.log;#error_log logs/error.log notice;#error_l ...
- 【C#】LINQ
一.什么是LINQ 长期以来,开发社区形成以下的格局: 1.面向对象与数据访问两个领域长期分裂,各自为政. 2.编程语言中的数据类型与数据库中的数据类型形成两套不同的体系,例如: C#中字符串用str ...
- angular 事件绑定
<button (click)="onClick($event)">点我</button> import { Component, OnInit } fro ...
- sqlServer组合主键
sqlServer 组合主键 创建表时: create table Person ( Name1 ) not null ,Name2 ) not null primary key(Name1,Na ...
- Android app如何加密?
欢迎访问网易云社区,了解更多网易技术产品运营经验. Android App包含的内容有dex文件,so文件,res,assets资源文件.对应的加密按此内容分为三大方面:dex保护.so加密.资源保护 ...