SAM做题记录

1|0SAM做题记录

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

题意:求S的所有出现次数大于1的子串的出现次数乘上长度的最大值。

思路:建出SAM后,预处理出每个节点的子串的出现次数,然后统计答案即可。

2.P2408 不同子串个数

题意:求不同子串个数。

思路:考虑到SAM上从根节点到每个节点的路径都是一个子串,因此一遍dfs即可。

3.P3975 [TJOI2015]弦论

题意:求一个字符串字典序第k小的子串。

思路:构建出SAM后,求出每个节点被经过的次数,然后判断k是否比当前节点能构造的所有子串个数大,再递归下去即可。

4.P6640 [BJOI2020] 封印

题意:给定字符串S,T,多次询问SlSrT的最长公共子串的长度。

思路:我们设fi表示S串以i结尾的子串与T的最长公共子串长度,这个可以对T建SAM,然后把S串跑一遍就可以了。这样答案就是maxi=lr{min(fi,il+1)},但是内层的min不好处理。我们考虑什么时候min取到fi,即fiil+1,就是ifi+1l,这时又有ifi是单增的(i变大1的时候,fi的变化量不超过1),所以我们可以二分找出临界点mid,那么答案就是max{imid+1,maxi=midrfi},这个过程可以用ST表做到一只log。

5.P4094 [HEOI2016/TJOI2016]字符串

题意:多次询问S[a,b]的所有子串和S[c,d]lcp的最大值。

思路:考虑二分答案,那么这样就变成了求一个子串有没有在另一个区间出现过,然后倍增找到SAM上对应的节点,然后还需维护可持久化线段树判断[a+mid1,b]里有没有终止接点即可,复杂度O(nlog2n)

6.P4770 [NOI2018] 你的名字

题意:多次询问,给出一个字符串T,求T有多少个本质不同的子串没有在[Sl,Sr]中出现过。

思路:先考虑l=1,r=|S|的情况。设limi表示[T1,Ti]的最长的是S的子串的后缀长度,tagi表示T的SAM上一个节点的endpos集合里最小的位置,那么答案就是

ans=i=2cntmax(0,lenimax(lenlinki,limtagi))

然后就考虑如果l,r不固定怎么办。这时需要用可持久化线段树合并维护endpos集合,求limi时,在这SAM上跑到了x,已经匹配了[Tilen+1,Ti],那么要匹配还得保证后继节点在[l+len,r]之间。复杂度O(|S|log(|S|)+|T|log|S|)

7.P6139 【模板】广义后缀自动机(广义 SAM)

题意:给定n个字符串,求本质不同字符串数量。

思路:这题关键是建广义SAM,其实就是建完一个串后把lst设为1即可。

8.CF666E Forensic Examination

题意:给定字符串ST1,T2Tm,多次询问,求S[l,r]T[L,R]的哪个串中出现次数最多,并输出次数。

思路:建出S和T的SAM,然后开可持久化线段树维护每个节点在哪个字符串中出现次数最多,询问时先倍增找到对应节点,然后直接在线段树上查询即可。

9.P3181 [HAOI2016] 找相同字符

题意:求两个串有多少个相同的子串(位置不同算不同)。

思路:建出广义SAM,答案就是SAM上每个节点在a串中的endpos集合大小乘上b串中的endpos集合大小在乘上有多少个这个节点代表多少个子串即可。


__EOF__

本文作者Xttttr
本文链接https://www.cnblogs.com/Xttttr/p/17263068.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Xttttr  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示