AC自动机:例题与机制详解

介绍

AC自动机是kmp算法trie树的结合
大体就是做这样的题用:
在这里插入图片描述
可以发现,这题和trie树的区别是把多个单词往一篇文章匹配,而trie恰好相反
匹配的时候其实就是判断子串,所以又用到了kmp
定义失配指针nxt[i]:表示root到nxt[i]结点的字符串是到 i 结点的字符串的在本树中的最长后缀(其实和kmp差不多啦)
设文章下一个字是s,当前trie树结点是a
每次发现a结点下方没有s的儿子(膝下无子 ) 就回去重新找失配指针
现在考虑处理失配指针
因为显然nxt[i]的深度小于i,所以采用bfs,从而保证当前结点以上的所有的结点的nxt都解决完

核心代码

void solve(){for(int i=1;i<=26;i++) tree[0][i]=1;int q[N]={};q[1]=1;nxt[1]=0;for(int st=1,ed=1;st<=ed;st++){int now=q[st];for(int i=1;i<=26;i++){if(!tree[now][i]) tree[now][i]=tree[nxt[now]][i];else{q[++ed]=tree[now][i];int v=nxt[now];nxt[tree[now][i]]=tree[v][i];}}}
}

看代码也可以发现,当tree[i][j]无定义时,直接指向了它的失配指针
然后就好办了

void ac(){int p=1;int l=strlen(s+1);for(int i=1;i<=l;i++) a[i]=s[i]-'a'+1;for(int i=1;i<=l;i++){p=tree[p][a[i]];int k=p;while(k>1){//防止遗漏ans+=end[k];end[k]=0;//本题需要清零k=nxt[k];}}return;
}

例题代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<stack>
#include<deque>
#include<set>
#include<string>
#include<iostream>
#include<climits>
#define mem(a,b) memset(a,b,sizeof(a));
using namespace std;
const int M=1000050;
const int N=100050;
const int mod=100003;
typedef pair<int,int>pr;
int m,n,k,b,c,d;
int num=1,tree[N][28],end[M];
char s[M];
int a[M];
void add(){int l1=strlen(s+1);for(int i=1;i<=l1;i++) a[i]=s[i]-'a'+1;int u=1;for(int i=1;i<=l1;i++){if(!tree[u][a[i]]) tree[u][a[i]]=++num;u=tree[u][a[i]];}end[u]++;
}
int nxt[N];
void solve(){for(int i=1;i<=26;i++) tree[0][i]=1;int q[N]={};q[1]=1;nxt[1]=0;for(int st=1,ed=1;st<=ed;st++){int now=q[st];for(int i=1;i<=26;i++){if(!tree[now][i]) tree[now][i]=tree[nxt[now]][i];else{q[++ed]=tree[now][i];int v=nxt[now];nxt[tree[now][i]]=tree[v][i];}}}
}
int ans=0;
void ac(){int p=1;int l=strlen(s+1);for(int i=1;i<=l;i++) a[i]=s[i]-'a'+1;for(int i=1;i<=l;i++){p=tree[p][a[i]];int k=p;while(k>1){ans+=end[k];end[k]=0;k=nxt[k];}}return;
}
int main(){scanf("%d",&k);while(k--){mem(tree,0);mem(end,0);ans=0;num=1;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%s",s+1);add();}scanf("%s",s+1);solve();ac();printf("%d\n",ans);}
}
/*
1
5
she
he
say
shr
her
yasherhs
*/

thanks for reading!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318716.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.NET Core实战项目之CMS 第七章 设计篇-用户权限极简设计全过程

写在前面这篇我们对用户权限进行极简设计并保留其扩展性。首先很感谢大家的阅读&#xff0c;前面六章我带着大家快速入门了ASP.NET Core、ASP.NET Core的启动过程源码解析及配置文件的加载过程源码解析并引入依赖注入的概念、Git的快速入门、Dapper的快速入门、Vue的快速入门。…

P4428-[BJOI2018]二进制【树状数组,set】

正题 题目链接:https://www.luogu.com.cn/problem/P4428 题目大意 长度为nnn的0/10/10/1串要求支持 修改一个位置求区间[l,r][l,r][l,r]有多少个子区间重排后的二进制数可以被三整除 1≤n≤1051\leq n\leq 10^51≤n≤105 解题思路 首先有22k%31(k∈Z)2^{2k}\%31(k\in Z)22k…

2021“MINIEYE杯”中国大学生算法设计超级联赛(5)Random Walk 2(推式子+矩阵逆+矩阵乘)

Random Walk 2 【2.4】Gauss-Jordan消元法求矩阵的逆 高斯消元求矩阵的逆&#xff0c;伴随单位矩阵一起消元即可。 [A,I]→[I,A−1][\text A,\text I]\to [\text I,\text A^{-1}][A,I]→[I,A−1] 移项变形&#xff0c;后就是个矩阵的逆&#xff0c;为啥赛时不写&#xff1f;&a…

牛客题霸 [顺时针旋转矩阵] C++题解/答案

牛客题霸 [顺时针旋转矩阵] C题解/答案 题目描述 有一个NxN整数矩阵&#xff0c;请编写一个算法&#xff0c;将矩阵顺时针旋转90度。 给定一个NxN的矩阵&#xff0c;和矩阵的阶数N,请返回旋转后的NxN矩阵,保证N小于等于300。 题解&#xff1a; 根据题目要求&#xff0c;先…

数论:扩展欧几里德(洛谷P1516 青蛙的约会)

欧几里德 基本思想&#xff1a;gcd(q,r)gcd(r,q%r); 证明&#xff0c;设q、r的最大公因数为a&#xff0c;则qxa&#xff0c;rya&#xff0c;xy互质 不妨设x>y&#xff08;显然如果小于会在一次gcd运算后交换&#xff09; 则q%r&#xff08;x%y&#xff09;*a 显然,其与r的最…

CF802O-April Fools‘ Problem(hard)【wqs二分,优先队列】

正题 题目链接:https://www.luogu.com.cn/problem/CF802O 题目大意 nnn天每条有aia_iai​和bib_ibi​。 每条可以花费aia_iai​准备至多一道题&#xff0c;可以花费bib_ibi​打印至多一道准备好了的题。 求准备kkk道题最少要花费多少。 1≤k≤n≤51051\leq k\leq n\leq 5\ti…

2021牛客暑期多校训练营3 G-Yu Ling(Ling YueZheng) and Colorful Tree(cdq分治)

G-Yu Ling(Ling YueZheng) and Colorful Tree HOWARLI题解 大致做法就是首先考虑哪些修改可能影响询问&#xff0c;当修改点权是询问的倍数时才可能影响询问。于是考虑把他们放在一起。 首先每次枚举每种询问的倍数&#xff0c;把这些修改和当前询问放在一起&#xff0c;由于…

参加胶东开发者技术大会有感

2015年的时候&#xff0c;也是在12月&#xff0c;我和Bob(https://www.cnblogs.com/nianming/)去北京参加了“全球架构师峰会”&#xff0c;在那次会议上&#xff0c;来自百度、腾讯、阿里巴巴、京东、美团、新浪微博、Twitter等公司的架构师、技术专家们分享了各自在架构方面的…

牛客题霸 [矩阵乘法] C++题解/答案

牛客题霸 [矩阵乘法] C题解/答案 题目描述 给定两个nn的矩阵A和B&#xff0c;求AB。 题解&#xff1a; 都学过矩阵相乘把&#xff0c;[i][k][i][j]*[j][k] 代码&#xff1a; class Solution { public:/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&…

专题:数列信息传递问题转化为图论合点问题(ybtoj-数列询问+序列破解)

文章目录前言&#xff1a;一、数列询问&#xff08;取模&#xff09;解析代码二、序列破解&#xff08;奇偶性&#xff09;解析代码thanks for reading&#xff01;前言&#xff1a; 在一个数列a中&#xff0c;对于一个大区间A和组成它的两个小区间a&#xff0c;b&#xff1b;…

CF786C-Till I Collapse【树状数组倍增,优先队列】

正题 题目链接:https://www.luogu.com.cn/problem/CF786C 题目大意 给出一个长度为nnn的序列。 对于每个k∈[1,n]k\in[1,n]k∈[1,n]求将nnn分成最少的段使得每段的长度不同。 1≤ai≤n≤1051\leq a_i\leq n\leq 10^51≤ai​≤n≤105 解题思路 考虑对于一个kkk我们的做法显然…

Docker最全教程——从理论到实战(五)

在笔者参加腾讯容器服务技术交流会时&#xff0c;我们了解到了藏区牧民的目前的生活艰辛状况&#xff0c;因此除了在同事朋友之间推荐其土特产之外&#xff0c;我们也在此进行初步分享&#xff0c;希望略尽绵薄之力&#xff0c;能够帮助到他们&#xff1a;货真价实、确保都是37…

2021牛客暑期多校训练营6 J-Defend Your Country(无向图点双+思维)

无向图联通分量 点u是割点&#xff0c;当且仅当 特判树根&#xff1a;u为树根&#xff0c;且u有多于1棵子树u不为树根&#xff0c;在递归树上u存在子节点v&#xff0c;满足&#xff1a;dfnu≤lowv\text{dfn}_u\leq \text{low}_vdfnu​≤lowv​ 如上图&#xff0c;v想走到u的组…

牛客题霸 [比较版本号] C++题解/答案

牛客题霸 [比较版本号] C题解/答案 题目描述 如果version1 > version2 返回1&#xff0c;如果 version1 < version2 返回-1&#xff0c;不然返回0. 输入的version字符串非空&#xff0c;只包含数字和字符.。.字符不代表通常意义上的小数点&#xff0c;只是用来区分数字…

不止代码:循环比赛(分治)

循环比赛日程表&#xff08;match&#xff09; 【问题描述】 解析 dfs或分治 分治可以不断递归4个小正方形 左上右下为前一半&#xff0c;左下右上后一半 dfs就很无脑了 代码 #include<cstdio> #include<cstring> #include<algorithm> #include<cmath…

P4983-忘情【wqs二分,斜率优化】

正题 题目链接:https://www.luogu.com.cn/problem/P4983 题目大意 给出长度为nnn的序列xxx&#xff0c;记平均数为xˉ\bar{x}xˉ&#xff0c;要求将序列分成mmm段。 每一段[l,r][l,r][l,r]的值为 ((∑ilrxixˉ)xˉ)2xˉ2\frac{((\sum_{il}^rx_i\times \bar x)\bar x)^2}{\bar…

前瞻科技,引领未来!Microsoft Connect(); 2018即将重磅来袭!

怎么用一句话点燃全球的开发者&#xff1f;——Microsoft Connect(); 2018即将重磅来袭&#xff01;每一个观点都能引发科技狂潮&#xff0c;每一项技术都将提速技术进程&#xff0c;由微软举办的 Microsoft Connect(); 2018 即将在太平洋时间12月4日8:30拉开帷幕&#xff01;大…

2021“MINIEYE杯”中国大学生算法设计超级联赛(7)Yiwen with Formula(任意模数FFT)

Yiwen with Formula 溢流眼泪题解 生成函数化成n个多项式乘积&#xff0c;然后分治把他们依次相乘&#xff0c;需要由于指数需要modϕ(998244353)998244353−1\bmod \phi(998244353)998244353-1modϕ(998244353)998244353−1&#xff0c;因此需要任意模数的FFT。。。 常数贼大…

牛客题霸 [ 孩子们的游戏] C++题解/答案

牛客题霸 [ 孩子们的游戏] C题解/答案 题目描述 每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开…

4.1模拟报告

总结 做的很坎坷。。。 一些细节上的玄学bug &#xff08;上次也一样。。。&#xff09; 还是要加强基础&#xff01;&#xff01;&#xff01; T1 x的实根 不贴了&#xff0c;就是水题。。。 T2 二分查找 就是lowerbound T3逆序对 1.树状数组 2.归并排序 注意&#xff…