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树,是一种树形结构,是哈希树的变种. 优点:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较. 性质:根节点不包含字符,除根节点外每一个 ...
随机推荐
- Linux日志文件分析
---恢复内容开始--- 日志保存位置 默认 var/log目录下 主要日志文件 内核及公共消息日志:message 计划任务日志:cron 系统殷桃日志:demsg 邮件系统日志:maillog 用 ...
- Docker学习之路(一)
容器简介 管理程序虚拟化(hypervisor virtualization, HV)是通过中间虚拟运行于物理硬件之上.而容器是直接运行在操作系统内核之上用户空间.因此,容器虚拟化运行也成为“操作系统 ...
- 基于 EntityFramework 的数据库主从读写分离架构(2)- 改进配置和添加事务支持
回到目录,完整代码请查看(https://github.com/cjw0511/NDF.Infrastructure)中的目录: src\ NDF.Data.EntityFramew ...
- c语言实践 统计输入的一串正整数里面奇数和偶数的个数
怎么考虑这个问题. 首先先确定肯定是需要一个变量保存输入的数据的,我们叫它input,最后结果要的是个数,所以需要另外两个变量来保存奇数的个数和偶数的个数. int input int countJ ...
- Luogu 3723 [AH2017/HNOI2017]礼物
BZOJ 4827 $$\sum_{i = 1}^{n}(x_i - y_i + c)^2 = \sum_{i = 1}^{n}(x_i^2 + y_i^2 + c^2 - 2 * x_iy_i + ...
- cakephp中sql查询in
$list = $this->Capital->find('all', array('conditions'=>array('remark in '=>array('银联支付' ...
- [redis]redis-cluster的使用
1.为集群添加一个主节点 首先准备一个全新的redis文件夹,这里我们叫做为7007 [root@CentOS7 redis-cluster]# ls [root@CentOS7 redis-clus ...
- javascript总结4:javascript常见变量
1 javascript变量 定义:变量在计算机中,是用于存储信息的"容器". 2 使用方法: 2-1 定义变量: var n1; 2-2 变量赋值: var n2=23.45; ...
- python -Tkinter 实现一个小计算器功能
文章来源:http://www.cnblogs.com/Skyyj/p/6618739.html 本代码是基于python 2.7的 如果是对于python3.X 则需要将 tkinter 改为Tk ...
- Bitmap类、BitmapFactory及BitmapFactory类中的常用方法
1.Bitmap 1.1非静态方法 public void recycle()——回收位图占用的内存空间,把位图标记为Dead public final boolean isRecycled() —— ...