
字符串—KMP/AC自动机
#
夕林山寸
这个作者很懒,什么都没留下…
展开
-
2020牛客暑期多校训练营(第二场) A All with Pairs KMP+hash
题目求的是前缀与后缀匹配长度平方和。由于后缀总共就1e6个。所以我们可以用hash把后缀存下来。然后枚举每个串的前缀,计算f(s,t)^2.但这样会重复:比如 :abbaaba枚举s为aba时当t是aba时,a计算了一次,ab也计算了一次,aba又计算了一次。所以我们从前往后枚举s串的前缀时,要减去与当前 前缀匹配的后缀,与之前前缀匹配的结果。比如:s为aba时。枚举到a,有ba,aba 的后缀与它匹配 ,ans+= 2* 1*1;枚举到ab,有...原创 2020-09-02 17:02:50 · 134 阅读 · 0 评论 -
2020牛客暑期多校训练营(第二场) A All with Pairs AC自动机 fail树上处理
有一个比较显然的思路:先把每个串插入到字典树中建立AC自动机枚举每个字符串做为t串,求f(s,t),我们知道AC自动机上fail[i]即:根节点到i节点路径上字符串最长的(当前字符串的后缀)与模式串的前缀匹配。类似于于KMP里的next。所以枚举了一个字符串t,s串一定在t串结尾字符节点u的fail树祖先链上。我们沿fail树链求贡献即可。但有个问题:上图是样例的字典树,红线是fail数组。绿线枚举t串为aba时,遍历6号节点的fail树链。贡献为: 在6号节点,有3*3=9原创 2020-09-01 21:14:51 · 165 阅读 · 0 评论 -
P4052 [JSOI2007]文本生成器 AC自动机 fail树上跑DP
//int dp[2][107][6007];// i为0/1是否满足出现一个模式串, 处理到第j位, 处于AC自动机第j号节点 的方案数建立fail树,类似AC自动机跑文本串的方法转移DP。v=tr[u][j];由于每个点连向j字符的点唯一,所以构造m长度的字符串后,停留在j点的方案数一定是不重复的,最终的方案数就是停留在所有节点构造出长度为m的字符串方案数总和。转移就是简单的dp转移。注意flag[i]表示构造到第i号节点,所组成的字符串是否出现过模式串。即相当于跑到每个节点,..原创 2020-09-01 17:05:27 · 186 阅读 · 0 评论 -
Computer Virus on Planet Pandora HDU - 3695 文本串正反跑一遍AC自动机
显然我们直接让文本串正反各跑一遍AC自动机更加方便。只是问模式串在AC自动机出现次数,所以直接消去flag标记即可。#include <cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<queue>using namespace std;typedef long long ll;#define re register#define l原创 2020-08-31 16:53:40 · 145 阅读 · 0 评论 -
病毒侵袭 HDU - 2896 AC自动机
AC自动机基础题,每个字符存一下是哪几个病毒的结尾字符。然后查询时直接存下来即可。注意每次flag要重新更新。#include <cstdio>#include<vector>#include<cstring>#include<iostream>#include<algorithm>#include<queue>using namespace std;typedef long long ll;#defi原创 2020-08-29 16:49:00 · 138 阅读 · 0 评论 -
P3808 【模板】AC自动机(简单版)
给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过。注意:是出现过,就是出现多次只算一次。AC自动机步骤:1:处理所有模式串,建立trie树:2:处理fail[i]数组:(最长的(当前字符串的后缀))在Trie上可以查找到)的末尾编号。显然fail[i]的深度一定小于i,所以可以BFS递推fail数组。而根据fail数组的定义,对于一个点u,他的fail数组求出过了,对于他的儿子v节点(是u指向i字符的儿子),若v存在,则v的fail为:tr[fail[u]][i]若v原创 2020-08-29 16:24:40 · 236 阅读 · 0 评论 -
Om Nom and Necklace CodeForces - 526D KMP处理循环节 + 数学取整运算证明
题意:求每个前缀是否是ABABA 的形式。(其中A有k+1个,B有k个,AB均可为空)对于一个前缀字符串i:令S=AB则可看成:SSSSA。若满足S的个数为k,则满足题意。对于前缀字符串i:其最小循环节e长度为:i-nxt[i], 改字符串可以看做:eeeex如果若干个e拼凑成一个S,使得S的数量为k,则满足题意。最后的x和前面若干个e组成A。具体判断的话我们可以分情况:下面是官方题解#include <bits/stdc++.h>using原创 2020-08-28 16:38:42 · 222 阅读 · 0 评论 -
Simpsons’ Hidden Talents HDU - 2594 连接串跑KMP
问s1前缀与s2后缀最大匹配。显然拼接两个串,然后跑KMP,(中间用分隔符,防止结果大于n)#include<cstring>#include<iostream> #include<vector>using namespace std;typedef long long ll;const int M = 1e6+7;char p[M],t[M];int nxt[M];int main(){ ios::sync_with_stdio(false原创 2020-08-27 13:35:47 · 125 阅读 · 0 评论 -
Seek the Name, Seek the Fame POJ - 2752 KMP水题
根据nxt数组的定义,就是前缀等于后缀最大的子串长度。for一遍也行,while(nxt[tp])也行。KMP这种东西尽量每次都手敲吧,最基础的算法没必要套板子#include<cstring>#include<iostream> #include<vector>using namespace std;typedef long long ll;const int M = 1e6+7;struct KMP{ char p[M],t[M];//模原创 2020-08-27 13:28:25 · 149 阅读 · 0 评论 -
Power Strings POJ - 2406 最小循环节长度
如果n%(n-nxt[n])==0,那么每一段len 都是相等的(根据kmp nxt数组的含义)#include<cstring>#include<iostream> using namespace std;typedef long long ll;const int M = 1e6+7;struct KMP{ char p[M],t[M];//模式串p,文本串t,p在t中出现次数,及位置, 下标1-n int nxt[M],n,m,f[M];//...原创 2020-08-27 13:13:32 · 192 阅读 · 0 评论 -
P3375 【模板】KMP字符串匹配 KMP 模板
好久没做KMP/AC自动机的题了,都快忘了。 就多校HDU做了一道,还是直接套的板子。这次准备手敲KMP/AC自动机,弄熟悉一点,做点经典题目。看了5min的B站KMP视频,手敲了板子一遍过。(现在的算法理解能力比之前快多了)回顾下KMP的算法吧:首先暴力的话:枚举文本串p所有位置(长度m),每个位置用模式串匹配(长度n)。复杂度n*m。而我们发现:形如:p: abababac, t=ababa时,暴力匹配非常低效因为我们在匹配p,和t时有很多额外信息被浪费了。我们...原创 2020-08-27 12:50:10 · 249 阅读 · 0 评论