想知道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. 学习 TList 类的实现[8]

    现在准备建立 Items 数组属性; 在 public 区输入下面代码:property Items[Index: Integer]: Pointer; 执行 Shift+Ctrl+C 后的代码是: ...

  2. jQuery动态生成Bootstrap表格

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...

  3. 阿里巴巴Java开发规约插件-体验

    插件有哪些功能? 阿里技术公众号于今年的2月9日首次公布<阿里巴巴Java开发规约>,瞬间引起全民代码规范的热潮,上月底又发布了PDF的终极版,大家踊跃留言,期待配套的静态扫描工具开放出来 ...

  4. 超全面的JavaWeb笔记day13<JSTL&自定义标签>

    1.JSTL标签库(重点) core out set remove url if choose when otherwise forEach fmt formatDate formatNumber 2 ...

  5. POJ 1252 Euro Efficiency(完全背包, 找零问题, 二次DP)

    Description On January 1st 2002, The Netherlands, and several other European countries abandoned the ...

  6. 墨卡托投影, GPS 坐标转像素, GPS 坐标转距离

    Before: 1. 研究的需要, 在 google map 上爬取了一些的静态卫星地图图片,每张图片的像素为 256*256 2. 通过 photshop 将这些地图碎片手动拼成了地图, 地图只是覆 ...

  7. 用rman恢复备库;遇到备库起不来一个案例 ORA-01152:ORA-01110

    数据从主库恢复到备库:打开备库发现出现异常 SQL> alter database open; alter database open * ERROR at line 1: ORA-10458: ...

  8. 【渗透测试学习平台】 web for pentester -7.文件包含

    Example 1 输入单引号,报错,得到物理路径 可通过../../../../etc/paaswd 读取敏感信息 可包含本地文件或远程文件 https://assets.pentesterlab. ...

  9. C# string.Format("{0:C3}", 2)

  10. STM32总线结构和存储器

    也就说我们所操作的就是别名区的位