「专题总结」后缀自动机

摘要:
后缀自动机关注自然,许多事情都关注区分概念。广义后缀自动机可以识别多个字符串的子字符串。5.找到S和T的最长公共子串,在S的后缀自动机上运行T匹配,如果不匹配,则剧烈跳转fa,得到以i结尾的最长后缀长度,每次都匹配S。叶子节点不超过20个,因此我们可以构建一个通用后缀自动机,每个叶子作为根,~~加上Deepinc~~的板。为M个字符串构建一个通用SAM,并考虑DP,处理l[i]是以i结尾的最长匹配后缀长度。

后缀自动机重点在于性质,东西很多注意区分概念。

  1. 后缀自动机是一个(DAG),从根开始的路径能够识别(S)的每个后缀(子串),一定不存在一条从根开始的路径能够识别不是S的子串。

  2. 点:每个节点代表了一个(endpos)类,从根到该节点的所有字符串在S中的出现位置相同,
    一个点代表的(endpos)集相同的各个串之间有后缀关系且连续,暂且称这些串的集合为(P)

  3. 边:走(trans)相当于在后边加字符,跳(parent)树则是在前面减字符。

  4. (nq)节点是为了划分不同的(endpos)集合,有自己的(len),但不是(S)的某个前缀,不具有(siz)

  5. 一个节点的(endpos)大小是(parent)树上的实点个数。

  6. 反串的(parent)树上,两点的(lcp)(lca)(len),注意x y为lca。

  7. 广义后缀自动机能够识别多个串的子串。

  8. (minlen(x)=maxlen(fa[x])+1),所以按(len)排序(桶排),可以得到(trans)拓扑序。

  9. 称一个节点(x)能够代表的字符串为根到x的所有路径((trans))上的字符排列,则每个节点代表的字符串不重不漏,本质不同。


应用:

1. 求本质不同子串

统计根到其他点的路径数,或(Ans=sumlimits_{i=2}^{tot}len[i]-len[fa[i]])

2. 求所有后缀的lcp

建反串的SAM,那么两个前缀实点的lcp是parent树上的lca的len,
由于是前缀不需要和(length)取min,拓扑统计过每个点(作为lca)的实点点对数。《差异》

3. 字典序最小循环串

复制一倍,建SAM,贪心地从'a'->'z'走(|S|)长。《工艺》

4. 每次加入字符,在线求本质不同子串

发现答案的增量只有(len[np]-len[fa[np]]),其他点内部守恒。《生成魔咒》

5. 求S和T的最长公共子串

在S的后缀自动机上跑T匹配,若失配则暴力跳fa(由于匹配一位在parent tree上深度至多+1
,跳fa深度一定-1,所以类似栈的势能复杂度分析, 为(O(lenth_T))),每次得到以i结尾的和S匹配的最长后缀长度(mx_i),那么(Ans=max(mx_i))

6. 求多个串的最长公共子串

(S_1)建SAM,同上对其余串在SAM上跑匹配,记录匹配(mx)信息在SAM的节点上,
表示该串在这个endpos相同的后缀串集合(P)中最多匹配到哪个长度,由于parent上的祖先有该后缀集合中所有串的后缀,
一个节点只要有mx值,就要把其parent树祖先(p)全部置为(len_p)。最后答案为在每个SAM节点上(所有串mx值最小值)的最大值。《公共串》

7. 求第K小子串

在DAG上dp出每个节点开始有多少条路径,从根开始走相当于不断缩小问题规模,
如果(k>dp[v])则跳过,否则走一步并减去答案串到点v的路径数。《弦论》
还是想说一下这个DP,如果要求本质不同,当(rd[u]=0)时就要++(dp[u]),表示无论这个点(这些串)的(|endpos|)多大,
我也只算一次,然后“带着”这个出现的贡献一直dp到根统计路径。
如果可以重复,那么就要有(du[u])+=(|endpos_u|),位置要算不同,实际上是在根到u的路径数上乘了(|endpos_u|)
同理有(sumlimits_{i=2}^{tot}(len[i]-len[fa[i]]) imes |endpos_i|=frac {n(n+1)}{2})

8. T在S中出现次数

在S的SAM上匹配T,如果失配说明S中不存在完整T,否则能找到在SAM上表示T的集合(P_u),T的出现次数就为(|endpos_u|)
如果要支持在线带修,需要打棵LCT维护动态parent树。维护子树和或者链加单点查都行。
注意第二种要给nq点赋同q点值《Substring》


##下面是一些不很模板的应用: ####B. 诸神眷顾的幻想乡(其实是广义模板) 求树上本质不同子串。叶子节点不超过20个,于是可以以每个叶子为根建广义后缀自动机,~~再加上Deepinc的板子~~。 本题给出了Trie,固定一个根rt,实际上一次dfs建出的SAM,和枚举叶子节点建出的SAM形态相同。因为q=las的特判。 在线建的复杂度为$Theta(|A||T|+G(T))$$|A|$为字符集大小,$|T|$为把所有串插入Trie的大小,$G(T)$是Trie上所有叶子深度之和。 DFS在线会被卡成$n^2$?不会证。。。
####H. Cheat 答案具有单调性,考虑二分L。 对M个串建广义SAM,处理出l[i]为以i结尾的最长匹配后缀长度。不能匹配到L就断开,因为之后的部分不到L就亏了。 区间划分问题,考虑DP。 设$f[i]$为i之前的最大熟悉长度,有转移$f[i]=max(f[i-1],f[j]+i-j),i-l[i] leq j leq i-L$ 因为$l[i] geq l[i+1]$,所以$i-l[i] leq i+1-l[i+1]$ 决策具有单调性,用单调队列优化下就可以$Theta(n)$check了。
SAM模板

void extend(int c){
	int p=las,np;np=las=++tot;
	len[np]=len[p]+1;
	for(;p&&!to[p][c];p=fa[p])to[p][c]=np;
	if(!p)fa[np]=1;
	else{
		int q=to[p][c];
		if(len[q]==len[p]+1)fa[np]=q;
		else{
			int nq=++tot;len[nq]=len[p]+1;
			F(i,0,25)to[nq][i]=to[q][i];
			fa[nq]=fa[q];fa[np]=fa[q]=nq;
			for(;p&&to[p][c]==q;p=fa[p])to[p][c]=nq;
		}
	}
}
   
广义SAM模板

void extend(int x){
	int p=las,q,nq,np;
	if(q=to[p][x]){
		if(len[q]==len[p]+1){las=q;return;}
		las=nq=++tot;len[nq]=len[p]+1;
		F(i,0,c)to[nq][i]=to[q][i];
		fa[nq]=fa[q];fa[q]=nq;
		for(;p&&to[p][x]==q;p=fa[p])to[p][x]=nq;
	}
	else{
		np=las=++tot;
		len[np]=len[p]+1;
		for(;p&&!to[p][x];p=fa[p])to[p][x]=np;
		if(!p)fa[np]=1;
		else{
			q=to[p][x];
			if(len[q]==len[p]+1)fa[np]=q;
			else{
				nq=++tot;
				len[nq]=len[p]+1;
				F(i,0,c)to[nq][i]=to[q][i];
				fa[nq]=fa[q];fa[q]=fa[np]=nq;
				for(;p&&to[p][x]==q;p=fa[p])to[p][x]=nq;
			}
		}
	}
}
   

免责声明:文章转载自《「专题总结」后缀自动机》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Typora常用操作Android属性之build.prop生成过程下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

回文自动机做题小结

模板 求以每个位置结尾的回文串的数量,加密输入 就是回文自动机节点的(len)数组,对应的是最长回文后缀 双倍回文 求形如(AA^rAA^r) 方法一:建立(fail)树,然后对每个(len)是偶数的点,在子树内找有没有长度为(2*len)的点,通过打标记做到(O(n)) 方法二:求一个与(fail)数组对应的(tran)数组,含义为长度不超过(frac{...

后缀自动机构建图解

目录 后缀自动机构建图解 case1 case2 case3 后缀自动机构建图解 我是在这学的:https://www.luogu.com.cn/blog/Kesdiael3/hou-zhui-zi-dong-ji-yang-xie 感觉作者画的图有点难理解,而且讲到了所以来画一画,方便复习。看本文前最好先把上面那个看一遍! 此处是从右往左增量,...

「学习笔记」AC自动机

还记得2019年暑假,gy在英乐华翻开ybt提高篇的目录 概述 通常来讲,KMP 算法用来处理单模式串匹配问题。而若要处理多模式串的问题,就要引出 AC自动机 。 AC自动机 是以 Trie 的结构为基础,结合 KMP 的思想建立的。 步骤 将所有模式串构建成一棵 Trie 树 对 Trie 上所有节点构造失配指针(最长后缀) 利用失配指针对主串进行匹配...

字符串匹配算法

一、简介 文本信息可以说是迄今为止最主要的一种信息交换手段,而作为文本处理中的一个重要领域——字符串匹配,就是我们今天要说的话题。(原文还特意提及文本数据数量每18个月翻一番,以此论证算法必须要是高效的。不过我注意到摩尔定律也是18个月翻番,这正说明数据的增长是紧紧跟随处理速度的,因此越是使用高效的算法,将来待处理的数据就会越多。这也提示屏幕前的各位,代码...