后缀自动机

时间:2021-07-31
本文章向大家介绍后缀自动机,主要包括后缀自动机使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

后缀自动机

水题清单

例题选记

P3804 【模板】后缀自动机 (SAM)

题意:

请你求出 S 的所有出现次数不为 1 的子串的出现次数乘上该子串长度的最大值。

做法:

把每次插入字符新建的节点时记为一,之后在parent树上将儿子的节点值累加到父亲上,该处的节点值即为此节点上所有字符串的出现次数,即可计算求出答案。

原理:

parent树上节点的祖先即为该节点后缀,但假如一个新字符时,即为该前缀的所有后缀的出现次数加 1,即让该节点上parent树上的所有祖先出现次数加 1.

P2408 不同子串个数

题意:

求本质不同子串个数。

做法:

枚举每个节点,该节点的 len 减去其父亲的 len 即为该节点代表的字符串的个数,累加求和即可。

题意:

求本质不同排名第k小的子串。

做法:

在建立出的后缀自动机的tire树上操作即可。

SP1811 LCS - Longest Common Substring

题意:

求2 个字符串的最长公共子串。

做法:

类似于KMP,在每次匹配失败时向上跳父亲,即为找其后缀,每一次跳完后比较答案。

P4248 [AHOI2013]差异

题意:

给定一个字符串,
求:
1⩽i<j⩽n∑​len(Ti​)+len(Tj​)−2×lcp(Ti​,Tj​)

lcp(a,b)表示字符串 a 和字符串 b 的最长公共前缀。

做法:

前两个一起算,lcp单独算。

将字符串翻转,即变为求每两个前缀的最长公共后缀。

任意两个前缀的最长后缀就在其 parent 树的 lca 上,因此在 parent 树上枚举此节点为多少节点的 lca 即可。记pt数组表示此节点是否表示前缀,siz为此子树上有多少个前缀。

[SDOI2016]生成魔咒

题意:

每插入一个字符时,当前本质不同的子串个数。

做法:

每插入一个字符,将其他节点向其连边时,将ans加上此节点代表子串数。

在字符类型过多时,在结构体里使用 map 存边。

原文地址:https://www.cnblogs.com/ezuyz/p/15085247.html