题目背景

通过套取数据而直接“打表”过题者,是作弊行为,发现即棕名。

这是一道简单的AC自动机模板题。

用于检测正确性以及算法常数。

为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交。

管理员提示:本题数据内有重复的单词,且重复单词应该计算多次,请各位注意

题目描述

给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过。

输入输出格式

输入格式:

第一行一个n,表示模式串个数;

下面n行每行一个模式串;

下面一行一个文本串。

输出格式:

一个数表示答案

输入输出样例

输入样例#1:
复制

2
a
aa
aa
输出样例#1: 复制

2

说明

subtask1[50pts]:∑length(模式串)<=10^6,length(文本串)<=10^6,n=1;

subtask2[50pts]:∑length(模式串)<=10^6,length(文本串)<=10^6;


题解

在通常就没什么人认真听的集训里,qwerta刚撸完一把Win7原装的扫雷,舒适的抬起头,正好对上了老师讲fail树的眼神。

所以是懂一丢丢手推方法的。

建议大家先构造点小数据手推,像是什么在$her,him,he,his,she$上匹配$shehisher$之类的。

网上教程也蛮多,就不画图了。(懒

其实是自己也推不蛮清楚

然后是教材QAQ yyb大佬的博客

总之,AC自动机就是在trie树上bfs一下然后乱搞,可以理解为trie上的KMP叭。

自己都不怎么会,就不讲这个东西了QAQ

 #include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define R register
const int MAXL=1e6+;
char s[MAXL];
struct emm{
int fail;
int nxt[];
int tag;
}AC[MAXL];//Tree结构体
queue<int>q;//get_fail的时候用的queue
int main()
{
//freopen("a.in","r",stdin);
ios::sync_with_stdio(false);
cin.tie(false);cout.tie(false);
int n;
cin>>n;
int tot=;
//trie
while(n--)
{
cin>>s;
int len=strlen(s);
int now=;//now表示当前的节点编号
for(R int i=;i<len;++i)
{
if(!AC[now].nxt[s[i]-'a'])//如果当前节点没有这个儿子
AC[now].nxt[s[i]-'a']=++tot;//就造个儿子
now=AC[now].nxt[s[i]-'a'];//now跳到这个儿子上
}
AC[now].tag++;//now最后在的地方是这个模式串的结束点,标记一下
}
//get_fail
{
//首先把跟0号节点相连的点处理一下
for(R int i=;i<;++i)
{
if(AC[].nxt[i])//如果这个儿子存在
{
AC[AC[].nxt[i]].fail=;//把fail指向0号节点(其实默认就是0啊QAQ
q.push(AC[].nxt[i]);//把这个儿子push进去
}
}
while(!q.empty())
{
int x=q.front();q.pop();//取点
for(R int i=;i<;++i)
{
if(AC[x].nxt[i])//如果这个儿子存在
{
AC[AC[x].nxt[i]].fail=AC[AC[x].fail].nxt[i];//敲重点!!!
//这个儿子的fail,等于这个节点fail的儿子 会手推就能懂叭QAQ
q.push(AC[x].nxt[i]);//push进去
}
else
AC[x].nxt[i]=AC[AC[x].fail].nxt[i];//这里直接把nxt指向了fail的对应儿子
}
}
}
//run
cin>>s;
long long ans=;
int len=strlen(s);
int now=;//now表示当前节点编号
for(R int i=;i<len;++i)
{
now=AC[now].nxt[s[i]-'a'];//往下走一层(因为之前直接把空的nxt往fail指了,所以不需要通常的while跳fail
//大概就是Trie图和Trie树的区别了叭
for(R int t=now;t&&AC[t].tag!=-;t=AC[t].fail)//从这个点开始暴力跳fail,找匹配
{
ans+=AC[t].tag;
AC[t].tag=-;//这是个剪枝
}
}
cout<<ans;
return ;//撒花
}

然后吐槽一下咕咕的数据,之前有一大段把$now$和$i$混用了,结果还过了一个点(???

「LuoguP3808」 【模板】AC自动机(简单版)的更多相关文章

  1. LG2444/BZOJ2938 「POI2000」病毒 AC自动机

    问题描述 LG2444 BZOJ2938 I \(\mathrm{AC}\)自动机 \(\mathrm{AC}\)自动机是一种多模式串匹配算法,本萌新今天刚学了它qwq 约定在构造\(\mathrm{ ...

  2. [模板][P3808]AC自动机(简单版)

    Description: 求n个模式串中有几个在文本串中出现 Solution: 模板,详见代码: #include<bits/stdc++.h> using namespace std; ...

  3. luoguP3808[模板]AC自动机(简单版)

    传送门 ac自动机模板题,裸的多串匹配 代码: #include<cstdio> #include<iostream> #include<algorithm> #i ...

  4. 洛谷.3808/3796.[模板]AC自动机

    题目链接:简单版,增强版 简单版: #include <cstdio> #include <cstring> const int N=1e6+5,S=26; char s[N] ...

  5. POJ 1625 Censored!(AC自动机->指针版+DP+大数)题解

    题目:给你n个字母,p个模式串,要你写一个长度为m的串,要求这个串不能包含模式串,问你这样的串最多能写几个 思路:dp+AC自动机应该能看出来,万万没想到这题还要加大数...orz 状态转移方程dp[ ...

  6. luoguP3796[模板]AC自动机(加强版)

    传送门 ac自动机模板,可能我写的ac自动机是有点问题的,所以跑的有些慢 暴力跳fail统计 代码: #include<cstdio> #include<iostream> # ...

  7. Ring HDU - 2296 AC自动机+简单DP和恶心的方案输出

    题意: 就是现在给出m个串,每个串都有一个权值,现在你要找到一个长度不超过n的字符串, 其中之前的m个串每出现一次就算一次那个字符串的权值, 求能找到的最大权值的字符串,如果存在多个解,输出最短的字典 ...

  8. 算法模板——AC自动机

    实现功能——输入N,M,提供一个共计N个单词的词典,然后在最后输入的M个字符串中进行多串匹配(关于AC自动机算法,此处不再赘述,详见:Aho-Corasick 多模式匹配算法.AC自动机详解.考虑到有 ...

  9. 模板 AC自动机

    题目描述 有$N$ 个由小写字母组成的模式串以及一个文本串$T$ .每个模式串可能会在文本串中出现多次.你需要找出哪些模式串在文本串$T$ 中出现的次数最多. 输入输出格式 输入格式: 输入含多组数据 ...

随机推荐

  1. mysql序列号发生器

    mysql序列号发生器 学习了:http://www.jquerycn.cn/a_14577 还可以这样啊:

  2. 百科知识 DCR文件如何打开

    使用IE可以打开,但是需要先安装Adobe Shockwave Player 天空软件下载地址:http://fpdownload.macromedia.com/get/shockwave/defau ...

  3. 多选checkbox

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. Quartz 2D编程指南(2)图形上下文(Graphics Contexts)

    Graphics Contexts       一个Graphics Context表示一个绘制目标(也能够理解为图形上下文).它包括绘制系统用于完毕绘制指令的绘制參数和设备相关信息.Graphics ...

  5. Coder-Strike 2014 - Round 2

    t题目链接:Coder-Strike 2014 - Round 2 A题:简单水题,注意能加入反复的数字.因此仅仅要推断是否能把Min和Max加入好.就能够了 B题:开一个sum计算每一个聊天总和,和 ...

  6. source insight 配置小记

    0/ Alt + T 打开 Document Options,设置字体,添加 C++ 类型文件 .cc , 删除 Plain txt 类型以避免添加 .txt 文件 1/ Alt + F12 切换函数 ...

  7. 搭建基于Jenkins的CI服务器

    安装Jenkins和创建任务这些操作网上一搜一大把,这里就没必要写了,直接就开始编译.单元测试,覆盖,git提交触发构建,构建失败发送给提交人邮件. 因为项目比较复杂,为了懒省事我直接在CI服务器上安 ...

  8. 二维码、条形码扫描——使用Google ZXing

    我在项目中用到了二维码扫描的技术,用的是Google提供的ZXing开源项目,它提供二维码和条形码的扫描.扫描条形码就是直接读取条形码的内容,扫描二维码是按照自己指定的二维码格式进行编码和解码. 可以 ...

  9. UIAlertController Changes in iOS 8

    本文转载至 http://www.th7.cn/Program/IOS/201409/276000.shtml   As part of the theme of iOS 8 to make inte ...

  10. Qtree3

    题目描述 给出N个点的一棵树(N-1条边),节点有白有黑,初始全为白 有两种操作: 0 i : 改变某点的颜色(原来是黑的变白,原来是白的变黑) 1 v : 询问1到v的路径上的第一个黑点,若无,输出 ...