Solution Set - SAM

讲解一些 SAM 经典的应用。可以结合 字 符 串 全 家 桶 中 SAM 的部分食用。

洛谷P2408

求不同子串个数。在 SAM 中,所有结点是一个等价类,包含的字符串互不相同。结点 u 中包含的子串数目就是 len(u)len(slink(u)),对所有结点求和即可。

洛谷P3804

丢到 SAM 上,会发现是要求每个结点的 endpos 大小。这个值等于它在 parent 树上子树内前缀结点的数目。前缀结点就是那些包含了整个字符串的某个前缀的结点。事实上,一个结点的 endpos 集合就是它子树内所有前缀结点的位置的集合。如果直接建出树来常数较大,可以按照 len 排序从大到小贡献,使用基数排序。

洛谷P4070

动态不同子串个数。考虑一次插入对答案的影响:

  • 如果只新建了一个结点,也就是前两个 case,这时原有结点的 slink 都没有修改,所以只用加上 len(cur)len(slink(cur))
  • 如果新建了两个结点,也就是第三个 case,此时 qslink 跑到了 r 上,rslink 又等于 q 原来的 slink,一进一出相当于没有变化,所以也只用加上 len(cur)len(slink(cur))

其实也很好理解,表示整个串的结点的 endpos 当然就是 {n},也就包含了所有新出现的子串。

另外这题范围很大,需要用 map 记转移。

CF235C

一个串循环发生了什么变化?删除开头字符,加上结尾字符。而这两个操作都是容易在 SAM 上完成的。后者就是自动机的转移,而前者只需要检查长度然后判断是否需要跳到 parent tree 上的父亲结点即可。具体到这道题上,我们相当于把询问串读入两遍,对每个前缀找到能够匹配的最长后缀,要求这个后缀的长度不超过询问串的长度。右移一位时,如果刚才匹配到了就先删除开头字符,然后再尝试加上结尾字符,如果不行就跳父亲。

洛谷P6640

这题更加直接的展示了 SAM 容易删除开头字符的特性:我们可以对每个 i 求出 s[1i] 出现在 t 中的最长后缀。具体地,在自动机上维护一个指针,表示当前的后缀。加入字符时,不断跳 parent 树上的父亲直到存在转移。求出这个最长后缀 fi 后,对每个询问二分答案,在 ST 表上查询区间最大值即可。

SPOJ-JZPGYZ

这道题需要使用广义 SAM。可以在每两个字符串之间加特殊字符,或者直接在处理完每个字符串之后把 lst0。给每个字符串的前缀位置染色,对于每个询问,找到这个字符串在广义 SAM 上对应的结点(如果不存在则答案为 0),然后答案就就是这个结点子树内的颜色数目。离线二维数点。

洛谷P3346

这一题同样需要广义 SAM。事实上上一题提到的两种 SAM 应当称为“伪广义 SAM”,它们可能会产生空结点。标准的广义 SAM 需要先建出 Trie 树,然后 BFS 遍历整棵树,记录下加入 Trie 树上每个结点之后 SAM 的 pos,每个结点就在父亲结点的 pos 基础上加入。回到本题,先对于每个叶子结点遍历一遍全树,建立 Trie 树,然后建出广义 SAM 求解即可。

CF653F

感觉做法有点抽象。仍然是建出 SAM。对于 SAM 的每个结点,取它 endpos 集合里的一个右端点,把这个长度区间丢到这个右端点上。然后对于每个右端点 r,一个合法的左端点 l 要求前缀和 sl1=sr,且 sr[l,r] 的最小值。对于后者可以倍增,对于前者可以拆成两个询问,离线,然后扫描一遍开桶统计。

CF1037H

建出字符串 S 的 SAM。对于一个询问串 T,字典序大于它的最小字符串一定是 T 的某个前缀 T1i 加上一个大于 Ti+1 的字符。那么在 SAM 上找到 T1i 对应的结点,遍历它大于 Ti+1 的出边,就只要判断到达的结点的子树内是否包含了一个 [L+i,R] 内的前缀结点。这可以用可持久化线段树维护 DFS 序实现。

SPOJ-REPEATS

这是一个 border 相关的问题。我们发现,如果一个串同时出现在两个位置,设这两个位置的差为 d,这个串的长为 len,则一定有一个字符串连续重复出现 lend+1 次,也就是开头不重叠的那一部分。所以只要求出每个点 endpos 集合内差的最小值即可。用线段树合并实现。

CF666E

这道题用到 SAM 的技巧是:要多次在模式串上匹配一个串的某个区间时,可以预处理出每个位置的最长匹配后缀,然后倍增跳 parent tree。剩下的就是一个线段树合并。

posted @   by_chance  阅读(49)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示