★★   输入文件: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自动机的更多相关文章

  1. 【BZOJ2754】喵星球上的点名(AC自动机)

    [BZOJ2754]喵星球上的点名(AC自动机) 题面 BZOJ 题解 友情提示:此题请不要在cogs上提交,它的数据有毒 对于点名串构建\(AC\)自动机 然后把名字丢进去进行匹配, 大力统计一下答 ...

  2. 基于trie树做一个ac自动机

    基于trie树做一个ac自动机 #!/usr/bin/python # -*- coding: utf-8 -*- class Node: def __init__(self): self.value ...

  3. AC自动机-算法详解

    What's Aho-Corasick automaton? 一种多模式串匹配算法,该算法在1975年产生于贝尔实验室,是著名的多模式匹配算法之一. 简单的说,KMP用来在一篇文章中匹配一个模式串:但 ...

  4. python爬虫学习(11) —— 也写个AC自动机

    0. 写在前面 本文记录了一个AC自动机的诞生! 之前看过有人用C++写过AC自动机,也有用C#写的,还有一个用nodejs写的.. C# 逆袭--自制日刷千题的AC自动机攻克HDU OJ HDU 自 ...

  5. BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2545  Solved: 1419[Submit][Sta ...

  6. BZOJ 3172: [Tjoi2013]单词 [AC自动机 Fail树]

    3172: [Tjoi2013]单词 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 3198  Solved: 1532[Submit][Status ...

  7. BZOJ 1212: [HNOI2004]L语言 [AC自动机 DP]

    1212: [HNOI2004]L语言 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1367  Solved: 598[Submit][Status ...

  8. [AC自动机]【学习笔记】

    Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)To ...

  9. AC自动机 HDU 3065

    大概就是裸的AC自动机了 #include<stdio.h> #include<algorithm> #include<string.h> #include< ...

随机推荐

  1. 通过url在两个页面之间传值

    今天开发遇到一个需要通过url传值才能解决的问题,就查了一下资料 一下是整理的结果: 假如需要把a页面的值传到b页面 a页面代码 <script type="text/javascri ...

  2. CF-799B

    B. T-shirt buying time limit per test 3 seconds memory limit per test 256 megabytes input standard i ...

  3. python类的特殊成员和方法

    变量或方法 描述 调用时机 __init__ 构造方法 通过类创建对象时,即类名() ,自动触发执行 __doc__ 表示类的描述信息   __module__ 表示当前操作的对象在那个模块   __ ...

  4. 剑指offer面试题:输入某二叉树的前序遍历和中序遍历,输出后序遍历

    二叉树的先序,中序,后序如何遍历,不在此多说了.直接看题目描述吧(题目摘自九度oj剑指offer面试题6): 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结 ...

  5. 洛谷 - P3786 - 萃香抱西瓜 - 状压dp

    重构一下就过了,不知道之前错在哪里. #include<bits/stdc++.h> using namespace std; typedef unsigned long long ull ...

  6. 如何设置Xcode模拟器地图的当前位置

    使用模拟器上的地图的话,需要设置当前位置,开启定位后,才能定位准确. 一.选中模拟器:Debug - Location - Custom Location 弹出的纬经度坐标.纬经度.纬经度坐标,默认显 ...

  7. ObjectArx 中反应器Reactor的使用

    反应器类派生于AcRxObject而不是AcDbObject,因为他们不是数据库对象,没有ID,拥有关系也不适用. 不同类型的反应器接收不同类型的通知事件.派生于AcDbDatabaseReactor ...

  8. TRANSFORM_TEX

    Shader "Custom/Exam1" { Properties { _MainTex ("Texture", 2D) = "white" ...

  9. [Xcode 实际操作]八、网络与多线程-(11)使用同步Post方式查询IP地址信息

    目录:[Swift]Xcode实际操作 本文将演示如何通过Post请求,同步获取IP地址信息. 一旦发送同步请求,程序将停止用户交互,直至服务器返回数据. 在项目导航区,打开视图控制器的代码文件[Vi ...

  10. MyBatis逆向工程代码的生成以及使用详解(持续更新)

    逆向工程简介什么是逆向工程:        mybatis需要程序员自己编写sql语句,mybatis官方提供逆向工程,可以针对单表自动生成mybatis执行所需要的代码(mapper.java.ma ...