想知道484每个萌新oier在最初知道AC自动机的时候都会理解为自动AC稽什么的,,,反正我记得我当初刚知道这个东西的时候,我以为是什么神仙东西$hhhhh$

首先要学AC自动机,就要先学会俩知识点:

trie树和kmp(我记得我都写了学习笔记,,,然而写得太烂了不想放上来了,,,网上随便搜篇题解都写得比我好的样子TT

好的那就当做已经掌握了这俩了来学习AC自动机趴!

首先要知道AC自动机是解决什么东西的嘛QwQ

kmp是一对一嘛,就是说一个字符串匹配一个字符串

然后AC自动机就是解决它没有解决的问题——一对多,一个字符串匹配多个字符串

这方面的题目比较多问法什么的也比较多我就以板子题1为例学下这个知识点好了QAQ

首先我们就读入所有模式串,建一棵trie树

然后就建fail指针

先说说fail指针是干什么的趴QwQ

举个eg好了,假如模式串有ace acd say she shr her ced 然后文本串是aced

于是构出来的trie树长这样(,,,图咕了$QAQ$

假如我们现在再匹配ace,那就当匹配到e之后就没有辣,那我们就找有麻油还能匹配的呢

那我们就和之前想kmp的时候一样,想着怎么利用之前做了的事儿呢,就想到,假如我能匹配ace,我就一定也能匹配ce,就一定也能匹配e这样子的对趴

所以我们就找啊,找trie树上有麻油一个点它及它之前的字符串和ace的后缀相同的

这个就是fail指针的作用了——记录每个点的表示的字符串的最长后缀指向哪个点

明白了麻油!我jio得还挺好理解的!

哦对了我好像没有解释为什么是最长后缀,,,?其实我jio得挺显然的?就是因为假如我有个ac还有个a,那我如果指向ac之后等ac匹配完了自然会去a的,可是如果指向的是a它不可能再指向ac了

get?

好大概思路就是这样的,具体实现和代码等下再说趴,,,QAQ

#include<bits/stdc++.h>
using namespace std;
#define ll int
#define rp(i,x,y) for(register ll i=x;i<=y;++i) const ll N=;
ll n,cnt,as;
struct tre{ll ed,nxt[],fail;tre(){ed=;memset(nxt,,sizeof(nxt));fail=;}}tr[N]; inline ll read()
{
register char ch=getchar();register ll x=;register bool y=;
while(ch!='-' && (ch>'' || ch<''))ch=getchar();
if(ch=='-')ch=getchar(),y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=getchar();
return y?x:-x;
}
inline void bd(string x)
{
ll lth=x.length()-,nwtr=;
rp(i,,lth){if(tr[nwtr].nxt[x[i]-'a'+]==)tr[nwtr].nxt[x[i]-'a'+]=++cnt;nwtr=tr[nwtr].nxt[x[i]-'a'+];}
++tr[nwtr].ed;
}
inline void fl()
{
queue<ll>Q;
rp(i,,)if(tr[].nxt[i])Q.push(tr[].nxt[i]);
while(!Q.empty())
{
ll nw=Q.front();Q.pop();
rp(i,,)
{
if(tr[nw].nxt[i]){tr[tr[nw].nxt[i]].fail=tr[tr[nw].fail].nxt[i];Q.push(tr[nw].nxt[i]);}
else tr[nw].nxt[i]=tr[tr[nw].fail].nxt[i];
}
}
}
inline void zdj(string str)
{
ll lth=str.length()-,nw=;
rp(i,,lth)
{
nw=tr[nw].nxt[str[i]-'a'+];
for(ll t=nw;t && tr[t].ed!=-;t=tr[t].fail)
{
as+=tr[t].ed;
tr[t].ed=-;
}
}
printf("%d\n",as);
} int main()
{
n=read();rp(i,,n){string str;cin>>str;bd(str);}fl();
string str;cin>>str;zdj(str);
return ;
}

这题要注意下,,,我只开大了点儿就MLE了QAQ!

umm我想了下,把几个板子题都放这儿好了QAQ

这是板子2号

这题差不多啊,就先把trie树建起来,fail按套路求一下,然后注意一下的是计数的时候有个小技巧,就是可以让是结尾的节点的end=单词号,非结尾的=0,然后每次在文本串中扫到的时候就直接as[end]++就好了,没了

哦还有一个,,,题解第二个的方法似乎很妙,一个优化,一个树上dp,有时间再搞,QAQ

放下代码QAQ

#include<bits/stdc++.h>
using namespace std;
#define ll int
#define rp(i,x,y) for(register ll i=x;i<=y;++i) const ll N=,M=;
ll n,cnt,as;
struct tre
{
ll ed,nxt[],fail,cs;
void clr(){ed=;memset(nxt,,sizeof(nxt));fail=;}
}tr[N];
struct ans{ll pos,as;void clr(){as=;pos=;}}ass[M];
bool gdgs=;
string str[M]; inline ll read()
{
register char ch=getchar();register ll x=;register bool y=;
while(ch!='-' && (ch>'' || ch<''))ch=getchar();
if(ch=='-')ch=getchar(),y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=getchar();
return y?x:-x;
}
inline bool cmp(ans gd,ans gs){return gd.as==gs.as?gd.pos<gs.pos:gd.as>gs.as;}
inline void bd(ll nm)
{
cin>>str[nm];ass[nm].clr();ass[nm].pos=nm;ll lth=str[nm].length()-,nw=;
rp(i,,lth)
{
if(tr[nw].nxt[str[nm][i]-'a'+]==)tr[nw].nxt[str[nm][i]-'a'+]=++cnt,tr[cnt].clr();
nw=tr[nw].nxt[str[nm][i]-'a'+];
}
tr[nw].ed=nm;
}
inline void fl()
{
queue<ll>Q;
rp(i,,)if(tr[].nxt[i])Q.push(tr[].nxt[i]);
while(!Q.empty())
{
ll nw=Q.front();Q.pop();
rp(i,,)
{
if(tr[nw].nxt[i])tr[tr[nw].nxt[i]].fail=tr[tr[nw].fail].nxt[i],Q.push(tr[nw].nxt[i]);
else tr[nw].nxt[i]=tr[tr[nw].fail].nxt[i];
}
}
}
inline void zdj()
{
string str;cin>>str;ll lth=str.length()-,nw=;
rp(i,,lth)
{
nw=tr[nw].nxt[str[i]-'a'+];
for(register ll j=nw;j;j=tr[j].fail)++ass[tr[j].ed].as;
}
} int main()
{
while(gdgs)
{
n=read();if(!n)exit();tr[].clr();cnt=;rp(i,,n)bd(i);fl();tr[].fail=;zdj();
sort(ass+,ass+n+,cmp);printf("%d\n",ass[].as);
cout<<str[ass[].pos]<<endl;rp(i,,n)if(ass[i].as==ass[i-].as)cout<<str[ass[i].pos]<<endl;else break;
}
return ;
}

,,,玄学事件?我开始打的是for(i)里套个for(i)也过去辣QAQ?

然后放下被安利的题目:

病毒

阿狸的打字机

单词

最短母串问题

阿最后说一下,还有一个小优化叫$last$优化,就将$fail$再优化了下,复杂度是没变的但实际上常有奇效$QwQ$

AC自动机板子题/AC自动机学习笔记!的更多相关文章

  1. Keywords Search HDU - 2222 AC自动机板子题

    In the modern time, Search engine came into the life of everybody like Google, Baidu, etc. Wiskey al ...

  2. AC 自动机刷题记录

    目录 简介 第一题 第二题 第三题 第四题 第五题 第六题 简介 这就是用来记录我对于<信息学奥赛一本通 · 提高篇>一书中的习题的刷题记录以及学习笔记. 一般分专题来写(全部写一起可能要 ...

  3. hdu 2222(AC自动机模版题)

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

  4. PSAPI和ToolHelpAPI学习笔记

    标 题: PSAPI学习笔记 作 者:北极星2003 时 间:2005-07-24 18:36 链 接:http://bbs.pediy.com/showthread.php?threadid=154 ...

  5. AC自动机学习笔记-2(Trie图&&last优化)

    我是连月更都做不到的蒟蒻博主QwQ 考虑到我太菜了,考完noip就要退役了,所以我决定还是把博客的倒数第二篇博客给写了,也算是填了一个坑吧.(最后一篇?当然是悲怆のnoip退役记啦QAQ) 所以我们今 ...

  6. AC 自动机学习笔记

    虽然 NOIp 原地爆炸了,目前进入 AFO 状态,但感觉省选还是要冲一把,所以现在又来开始颓字符串辣 首先先复习一个很早很早就学过但忘记的算法--自动 AC AC自动机. AC 自动机能够在 \(\ ...

  7. 学习笔记:AC自动机

    话说AC自动机有什么用......我想要自动AC机 AC自动机简介:  首先简要介绍一下AC自动机:Aho-Corasick automation,该算法在1975年产生于贝尔实验室,是著名的多模匹配 ...

  8. HDU 2222 AC自动机模板题

    题目: http://acm.hdu.edu.cn/showproblem.php?pid=2222 AC自动机模板题 我现在对AC自动机的理解还一般,就贴一下我参考学习的两篇博客的链接: http: ...

  9. HDU 3065 (AC自动机模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3065 题目大意:多个模式串,范围是大写字母.匹配串的字符范围是(0~127).问匹配串中含有哪几种模 ...

随机推荐

  1. 弹窗插件zDialog使用教程

    1.首先现在好zDialog然后复制项目中 2.配置zDialog解压以后images文件夹位置 images存放位置根据自己实际项目而定,zDialog.js中配置位置即可,如: var IMAGE ...

  2. Windows下配置Apache+PHP跑Wordpress拾遗

    首先,我很少这么做,因为一旦有跑WAMP的需求,我就直接下一个wamp的安装包就可以了,市面上数不胜数,我一直用的是EasyPHP,不是说它有多好,而是很多年前第一次用后没什么问题,就一直用下来了.这 ...

  3. CSS清除浮动常用方法小结

    1.使用空标签清除浮动.我用了很久的一种方法,空标签可以是div标签,也可以是P标签.我习惯用<P>,够简短,也有很多人用<hr>,只是需要另外为其清除边框,但理论上可以是任何 ...

  4. 最全Java学习路线图——Java学习指南

    准备篇 适用/适合人群:适合基础小白 目标:掌握JavaSE. ●技术点小节: 1.开发工具的安装配置的介绍 2.JDK安装 3.DOS环境编程 4.Eclipse的安装使用 ●JAVA基础 1.基本 ...

  5. liunx下误删除/var目录下的empty文件,导致ssh连接不上

    清理Liunx上不用的文件,导致误删 /var/下的empty文件,因为用的是ftp删的,所以可能有隐藏文件没有看到,导致其他同事都登录不上去 解决方法: 1.在/var文件夹下,重新建立empty文 ...

  6. mysql数据库,如何进行数据目录的初始化操作

    需求描述: 当将mysql的二进制包解压之后,只有通过初始化数据库的数据目录,创建系统表之后才能使用mysql Server 数据库版本:5.5.57-log 操作过程: 1.通过解压之后的mysql ...

  7. 如何:为 IIS 7.0 配置 <system.webServer> 节

    https://technet.microsoft.com/zh-cn/sysinternals/bb763179.aspx https://www.cnblogs.com/tl2f/p/501615 ...

  8. YARN应用程序开发和设计流程

    从业务的角度看,一个应用需要分两部分进行开发,一个是接入YARN平台,实现3个协议,通过YARN实现对集群资源的访问和利用:另一个是业务功能的实现,这个与YARN本身没有太大关系.下面主要阐述如何将一 ...

  9. CentOS6.4环境下布署LVS+keepalived笔记

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://400053.blog.51cto.com/390053/713566 环境: 1 ...

  10. Swift-Debug下打印函数名和行数

    1.Build Settings ->搜索 Swift compiler -> OTHER_SWIFT_FLAGS = -D DEBUG 2.设置DEBUG函数 配置好后就可以愉快的进行调 ...