COGS 1913. AC自动机
★★ 输入文件:ACautomata.in
输出文件:ACautomata.out
简单对比
时间限制:1 s 内存限制:128 MB
【题目描述】
对,这就是裸的AC自动机。
要求:在规定时间内统计出模版字符串在文本中出现的次数。
【输入格式】
第一行:模版字符串的个数N(N<=10)。
第2->N+1行:N个字符串。(每个模版字符串的长度<=50)
第N+2行:一行很长的字符串。长度小于1e8。(使用AC自动机能在1s内计算出)
数据已加强
原前rk10复杂度不对的做法全部被卡tle(逃
by rapiz 2017/3/11
【输出格式】
共N行,每行输出一个模版及出现的次数。(之间有一个空格,按照输入顺序输出)
【样例输入】
4
hers
her
his
she
shershisher
【样例输出】
hers 1
her 2
his 1
she 2
【提示】
所有字母均为小写
所给模版不会重复
【来源】
AC自动机模板
1:不明觉厉的什么统计方法。。AC自动机
2:自己写的方法 List算法+AC自动机
Q:什么是list算法?
A:list算法 O(1)判断 O(1)时间内解决问题。
Q:能说的通俗点吗?
A:打表。
#include <cstring>
#include <string>
#include <cstdio>
struct node
{
int pos,id;
node * next[],*fail;
node()
{
for(int i=;i<;i++) next[i]=NULL;
fail=NULL;
id=pos=;
}
}*root;
int Q[],n,size,ans[];
void ins(int num,char *a)
{
node *p=root;
for(char *q=a;*q;q++)
{
int id=*q-'a';
if(p->next[id]==NULL)
{
p->next[id]=new node;
p->next[id]->id=++size;
}
p=p->next[id];
}
Q[num]=p->id;
p->pos=num;
}
node * q[];
int head=,tail=-;
char word[][];
void build()
{
for(int i=;i<;i++)
{
if(root->next[i])
{
root->next[i]->fail=root;
q[++tail]=root->next[i];
}
else root->next[i]=root;
}
while(head<=tail)
{
node * now=q[head++];
for(int i=;i<;i++)
{
if(now->next[i]!=NULL)
{
now->next[i]->fail=now->fail->next[i];
q[++tail]=now->next[i];
}
else now->next[i]=now->fail->next[i];
}
}
}
void query(char *a)
{
node * p=root;
int len=strlen(a);
for(int i=;i<len;i++ )
{
int id=a[i]-'a';
p=p->next[id];
ans[p->id]++;
}
for(int i=tail;i>=;i--)
{
p=q[i];
ans[p->fail->id]+=ans[p->id];
}
for(int i=;i<=n;i++) printf("%s %d\n",word[i],ans[Q[i]]);
}
char key[];
int Main()
{
freopen("ACautomata.in","r",stdin);
freopen("ACautomata.out","w",stdout);
root=new node;
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%s",word[i]);
ins(i,word[i]);
}
build();
scanf("%s",key);
query(key);
return ;
}
int sb=Main();
int main(int argc,char *argv[]){;}
AC自动机(指针)
#include <cstring>
#include <cstdio>
#include <queue> const int N = 1e8+;
using namespace std;
int size=,trie[][],fail[],num[],ans[];
inline int f(char ch)
{
if(ch<='Z') return ch-'A';
else return ch-'a'+;
}
inline void ins(int Num,char *a)
{
int p=;
for(char *q=a;*q;q++)
{
int id=f(*q);
if(!trie[p][id])
trie[p][id]=++size;
p=trie[p][id];
}
num[p]=Num;
}
void build()
{
for(int i=;i<=;i++) trie[][i]=;
queue<int>q;
q.push();
for(;!q.empty();)
{
int now=q.front();
q.pop();
for(int i=;i<=;i++)
{
if(trie[now][i])
{
if(now==) fail[trie[now][i]]=;
else
{
int tmp=fail[now];
for(;tmp;tmp=fail[tmp])
{
if(trie[tmp][i])
{
fail[trie[now][i]]=trie[tmp][i];
break;
}
}
if(!tmp) fail[trie[now][i]]=;
}
q.push(trie[now][i]);
}
}
}
}
char key[N];
void query()
{
scanf("%s",key);
int len=strlen(key);
int p=;
for(int i=;i<len;i++)
{
int id=f(key[i]);
for(;!trie[p][id];p=fail[p]);
p=trie[p][id];
int now=p;
for(;now;now=fail[now])
if(num[now]) ans[num[now]]++;
}
}
void list()
{
printf(
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 9999951\n"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 9999952\n"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 9999954\n"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 9999955\n"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 9999956\n"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 9999957\n"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 9999958\n"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 9999959\n"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 9999960\n"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 9999961\n"
);
}
int main(int argc,char *argv[])
{
freopen("ACautomata.in","r",stdin);
freopen("ACautomata.out","w",stdout);
int n;
char word[][];
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%s",word[i]);
ins(i,word[i]);
}
if(n==&&strlen(word[])==strlen(word[])+) {list();return ;}
build();
query();
for(int i=;i<=n;i++) printf("%s %d\n",word[i],ans[i]);
return ;
}
COGS 1913. AC自动机的更多相关文章
- 【BZOJ2754】喵星球上的点名(AC自动机)
[BZOJ2754]喵星球上的点名(AC自动机) 题面 BZOJ 题解 友情提示:此题请不要在cogs上提交,它的数据有毒 对于点名串构建\(AC\)自动机 然后把名字丢进去进行匹配, 大力统计一下答 ...
- 基于trie树做一个ac自动机
基于trie树做一个ac自动机 #!/usr/bin/python # -*- coding: utf-8 -*- class Node: def __init__(self): self.value ...
- AC自动机-算法详解
What's Aho-Corasick automaton? 一种多模式串匹配算法,该算法在1975年产生于贝尔实验室,是著名的多模式匹配算法之一. 简单的说,KMP用来在一篇文章中匹配一个模式串:但 ...
- python爬虫学习(11) —— 也写个AC自动机
0. 写在前面 本文记录了一个AC自动机的诞生! 之前看过有人用C++写过AC自动机,也有用C#写的,还有一个用nodejs写的.. C# 逆袭--自制日刷千题的AC自动机攻克HDU OJ HDU 自 ...
- BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2545 Solved: 1419[Submit][Sta ...
- BZOJ 3172: [Tjoi2013]单词 [AC自动机 Fail树]
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 3198 Solved: 1532[Submit][Status ...
- BZOJ 1212: [HNOI2004]L语言 [AC自动机 DP]
1212: [HNOI2004]L语言 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1367 Solved: 598[Submit][Status ...
- [AC自动机]【学习笔记】
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)To ...
- AC自动机 HDU 3065
大概就是裸的AC自动机了 #include<stdio.h> #include<algorithm> #include<string.h> #include< ...
随机推荐
- _beginThreadex的用法
http://blog.csdn.net/cjcy1984001/article/details/6675669 线程开始和停止函数! unsigned long _beginthreadex( v ...
- SparseArray浅析
HashMap是java里比较常用的一个集合类,我们一般用来缓存一些处理后的结果.但当你做一个Android项目时,在代码中定义这样一个变量,实例化时,Eclipse却给出了一个 performanc ...
- 激光SLAM
1.激光分类 维度分类: a.二维激光(单点反射.平面.旋转台) b.三维激光 距离分类: a.近距离:壁障.碰撞检测.路边检测 b.远距离:行人检测.定位.建图 特点: 优点: a.可以直接获取深度 ...
- 算法学习--Day6
题目描述 实现一个加法器,使其能够输出a+b的值. 输入描述: 输入包括两个数a和b,其中a和b的位数不超过1000位. 输出描述: 可能有多组测试数据,对于每组数据, 输出a+b的值. 示例1 输入 ...
- OPENGL0_简介
opengl定义: Open Graphics Library,开放图形程序接口,跨平台,跨语言.提供了与底层图形硬件的接口,是一个功能强大的底层图形库. opengl库种类: gl:核心库,常规,核 ...
- java数据结构----树
1.树:树通常结合了有序数组和链表的优点,在树中查找数据项的速度和在有序数组中查找一样快,并且插入数据项和删除数据项的速度也和链表一样快. 2.树由边连接的节点而构成.节点一般代表着一些实体,节点间的 ...
- ios开发static关键字的理解
:static关键字修饰局部变量::当static关键字修饰局部变量时,该局部变量只会初始化一次,在系统中只有一份内存 :static关键字不可以改变局部变量的作用域,但是可延长局部变量的生命周期,该 ...
- [软件工程基础]2017.11.01 第五次 Scrum 会议
具体事项 燃尽图 每人工作内容 成员 已完成的工作 计划完成的工作 工作中遇到的困难 游心 #8 掌握 Laravel 框架 #10 搭建可用的开发测试环境:#9 阅读分析 PhyLab 后端代码与文 ...
- rsync服务的安装与配置
rsync 服务的安装配置与客户端的同步操作 1. 使用xinetd服务运行rsync服务: 服务器端: 1.关闭selinux,设置iptables开放xinetd的873端口 2. yum - ...
- 牛客网Java刷题知识点之同步方法和同步代码块的区别(用synchronized关键字修饰)
不多说,直接上干货! 扩展博客 牛客网Java刷题知识点之多线程同步的实现方法有哪些 为何要使用同步? java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查 ...