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< ...
随机推荐
- React-Native 基本环境的搭建
看了一些RN资料,仅仅了解到人们对 RN(以下简称 React_native 框架) 的使用描述以及评价,就觉得RN是一个很不错的框架,值得学习.今天就开始写我的学习记录,也给大家分享一下.下面进入正 ...
- vim opencv
http://blog.csdn.net/fdl19881/article/details/7275203 ctags .vim: http://www.vim.org/scripts/script. ...
- 8、html的body内标签之fieldset标签和label标签
一.label标签 <label> 标签为 input 元素定义标签(label). label 元素不会向用户呈现任何特殊的样式.不过,它为鼠标用户改善了可用性,因为如果用户点击 lab ...
- DOM学习笔记(三)DOM元素的访问、修改与事件
访问 HTML 元素等同于访问节点,使用的是document对象下的数个getElement方法,然后再对返回的元素(或元素列表)进行具体内容的访问和修改,或者响应对应的事件是操作 一些 DOM 对象 ...
- Spring Boot 学习系列(09)—自定义Bean的顺序加载
此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. Bean 的顺序加载 有些场景中,我们希望编写的Bean能够按照指定的顺序进行加载.比如,有UserServ ...
- Linux命令之清空当前文件
vi进入文件 英文状态下按下 / 输入 %d 执行 清空当前文件 over!O(∩_∩)O哈哈~
- 两种好用的清除浮动的小技巧(clearfix hack)
方法一:使用内容生成的方式清除浮动 这种方法不能解决margin在垂直边界上的叠加问题,如果不涉及margin的边界叠加问题使用这种方法清除浮动就行了 . /* :after 选择器向选定的元素之后插 ...
- [Xcode 实际操作]三、视图控制器-(2)UITabBarController选项卡(标签)视图控制器
目录:[Swift]Xcode实际操作 本文将为你演示,选项卡视图控制器的创建和使用. 在项目文件夹[DemoApp]上点击鼠标右键,弹出右键菜单. [New File]->[Cocoa Tou ...
- C 语言实例 - 字符串翻转
C 语言实例 - 字符串翻转 C 语言实例 C 语言实例 使用递归来翻转字符串. 实例 - 字符串翻转 #include <stdio.h> void reverseSentence(); ...
- subsets(2018.10.16)
一句话题意:给你一个包含n个元素的集合,问有多少个非空子集,能划分成和相等的两份.(n<=20) 题解:对于这道题,我们很轻易可以列出\(O(3^n)\)的暴力,这是显然过不了的,观察这道题的性 ...