首页 > 其他分享 >SAM 练习题

SAM 练习题

时间:2024-03-24 09:12:44浏览次数:26  
标签:练习题 子串 SAM text 线段 len link

两个技巧:

  • SAM 匹配,删除最前面字符

  • 后缀树路径上,字符串长度连续

  • 一个区间的子串可以倍增得到

线段树合并维护 \(\text{endpos}\)

SP687

link

考虑周期转 Border,一个存在的 Border 为 \(\text{lcp}(i,j)\),对应周期为 \(|i-j|\),周期出现整次数为 \(\dfrac{|i-j|}{\text{lcp}(i,j)}\)。线段树合并求出每个子串的 \(\text{endpos}\),然后求相邻位置之间距离的最小值。

Luogu4094 [HEOI2016/TJOI2016] 字符串

link

二分长度,相当于求一个子串是否在另一个子串内出现过。

线段树合并求出 \(\text{endpos}\),只需要判断一段区间是否有值。

Luogu4384 制胡窜

link

先线段树合并,求出 \(\text{endpos}\)。

考虑我们选两个位置,相当于用两个长度为 \(len-1\) 的区间覆盖所有 \(\text{endpos}\) 位置,我们要求这个方案数。

如果覆盖不了所有点,无解。

否则分讨:

  • 所有点可以被一个区间覆盖

那么我们枚举第一个区间覆盖了多少个点,设为 \(i-1\),贡献为 \((p_i-p_{i-1})(len-(p_k-p_i))=(len-p_k)(p_i-p_{i-1})+p_i(p_i-p_{i-1})\)。

边界特判,两边贡献分别为 \((p_1-len-1)(len-(p_k-p_1)),\sum\limits_{j=p_k-len+1}^{p_1} (n+1-j)\),后者是等差数列求和。

  • 所有点不可以被一个区间覆盖

设左边能覆盖到 \(L\) 个点,右边 \(R\) 个点。

当 \(L<R\) 时:方案数为 \((len-(p_L-p_1))(len-(p_k-p_R))\)。

当 \(L\ge R\) 时:

枚举第一个区间覆盖到的位置 \(i-1\),贡献为 \((p_i-p_{i-1})(len-(p_k-p_i))=(len-p_k)(p_i-p_{i-1})+p_i(p_i-p_{i-1})\)。

边界特判,右边卡极限为 \((p_R-p_{R-1})(len-(p_k-p_R))\),左边卡极限为 \((len-(p_L-p_1))(len-(p_k-p_{L+1}))\)。

维护 \(\sum (p_i-p_{i-1}),\sum p_i(p_i-p_{i-1})\) 即可。

SAM 上跑匹配

Luogu4022 [CTSC2012] 熟悉的文章

link

二分,我们只要求零散字符数量的最小值。

考虑 dp,设 \(f[i]\) 为以 \(i\) 结尾的答案。

考虑匹配,求出每个位置结尾的最长公共子串,设子串开头为 \(p_i\)。

那么 \(f[i]=\min_{j=p_i-1}^{i-mid} \{f[j]+1\}\)。

使用单调队列,时间复杂度 \(O(n\log n)\)。

Luogu4770 [NOI2018] 你的名字

link

枚举 \(T\) 的子串的结尾位置 \(i\),我们当前要算的子串开头位置是一段前缀,考虑求出这个前缀位置。

算的子串不能重复,所以对 \(T\) 建立 SAM,可以通过插入的点得知与 \(T\) 不重复的前缀位置。

还有 \(S\) 的限制,我们考虑在 \(S\) 的 SAM 上跑匹配,求出 \(i\) 位置结尾的最长公共子串,每次只用判断一段区间内是否有某一子串的结尾位置。

线段树合并维护 \(S\) 的 \(\text{endpos}\) 即可。

配合 DSU on Tree/重链剖分

Luogu5576 [CmdOI2019] 口头禅

link

建立广义 SAM,每个字符串给对应的 SAM 点染对应颜色,我们要求的是同时包含 \([l,r]\) 所有颜色的子串长度最大值。

考虑倒序枚举每个子串,做 DSU on Tree,用 set 动态维护颜色连续段。

每合并出一个新段,我们拿这个段查一下,看看包含哪些询问区间,逐次更新即可。

Luogu4482 [BJWC2018] Border 的四种求法

link

要求的是 \(\max\limits_{i\in [l,r],\text{lcs}(i,r)\ge i-l+1}\{i\}\)。

建立前缀树,我们可以从 \(r\) 位置往上跳,然后查找子树内最大的合法的 \(i\)。

可惜会超时,还有另一种方法:询问离线,然后一遍 DFS,每次递归进入一个子树时,把其他子树的信息丢进一个线段树里。

用重链剖分平衡两种做法:

  • 往上跳,跳轻边时,查询子树内最大的合法的 \(i\),用线段树合并然后线段树二分即可。

  • 对于重链,我们可以一遍 DFS,然后暴力把轻子树的点全部丢进线段树内。

时间复杂度 \(O(n\log n)\)。

CF1098F Ж-function

link

考虑我们要求的是 \(\sum_{i=l}^r \min(r-i+1,\text{lcp}(l,i))\)。

可以这样想:我们把 \([i,i+\text{lcp}(l,i)-1]\) 这一段 \(+1\),然后查询 \([l,r]\) 的总和。

当然直接跳链也是可以的,用重链剖分平衡两种做法:

  • 跳轻边时,查询子树,线段树合并。

  • 对于重链,我们暴力加入轻子树的信息,然后对于询问,查询 \([l,r]\) 的总和。

注意查询时要剔除 \(i<l\) 的贡献,使用 CDQ 分治,时间复杂度 \(O(n\log ^3 n)\)。

CF 有 64bit 语言 可以过,但是 Luogu 不能过。

标签:练习题,子串,SAM,text,线段,len,link
From: https://www.cnblogs.com/Sktn0089/p/18092066

相关文章

  • [周报]线性代数和SAM 2024年3月第3周
    算法笔记线性代数线代题不多,但是都很有些难度.当然OI中的线性代数存在很大程度上的"只取所需"的情况.高斯消元,线性(异或)基加上矩阵优化DP,基本上就是最多的一个运用了.高斯消元道理就是初中数学,解多元一次方程组.其实这种用方程组来理解线代是个挺直观的方法.比如向量张成......
  • 第一章 计算机网络概述——提纲 + 练习题(体系结构相关习题、时延计算相关习题)
    文章目录第一章计算机网络概述1.2因特网概述1.3三种交换方式1.4计算机网络的分类1.5计算机网络的性能指标1.6计算机网络的体系结构(重点、难点)第一章-习题第一部分-体系结构相关1、2、3、4、5、6、7、8、9、10、练习题第二部分-时延相关1、2、3、4、5、第一......
  • ubuntu 搭建Samba服务
    1.sudoapt-getinstallsamba2.sudocp/etc/samba/smb.conf/etc/samba/smb.conf.bak3.sudovi/etc/samba/smb.conf在smb.conf的文件最后加入以下配置并保存,然后退出[work] #ubuntu下的共享目录名称comment=sambahomedirectorypath=/home/book/ #共享目......
  • Tomcat 9.0 conf server.xml sample
    C:\ProgramFiles\ApacheSoftwareFoundation\Tomcat9.0\conf\server.xml <Connectorprotocol="HTTP/1.1"port="8080"maxThreads="200"connectionTimeout="20000"......
  • 芒果YOLOv5改进86:上采样Dysample:顶会ICCV2023,轻量级图像增采样器,通过学习采样来学习上
    ......
  • 树莓派从零开始搭建Samba文件服务器
    树莓派买回来闲置了许久,之前一直有在家局域网看视频学习的需求,周末抽空把树莓派折腾好,搭建了个Samba服务作为文件服务器,挂载磁盘,可以通过ipad或是电脑局域网连接,看剧美滋滋(ノ´ヮ´)ノ*:・゚✧1、树莓派刷机教程树莓派官网第一个带桌面镜像,第二个是带桌面并且带推荐软件的镜像,这里......
  • [数组练习题]二分法查找操作实例:使用二分法查找有序数组中元素。 找到返回索引,不存在
    文章目录题干一、题目分析1.定义数组,用于后续在数组中查找元素2.对数组进行排序3.定义方法4.调用方法,打印输出二、代码1.代码块2.一图流总结题干提示:这段是题干,仔细阅读仔细分析:二分法查找操作:使用二分法查找有序数组中元素。找到返回索引,不存在输出-1。......
  • 概率期望进阶 + Min-Max容斥 练习题
    Luogu5644[PKUWC2018]猎人杀link题意:有\(n\)个人,每次在剩下的人中选择一个人杀死,选择\(i\)的概率为\(\dfrac{w_i}{\sum_jw_j}\),求第\(1\)个人是最后一个杀死的概率,答案对\(998244353\)取模。\(w_i\ge1,\space\sum\limits_{i=1}^nw_i\le10^5\)考虑容斥,枚举钦定......
  • Debian 12.4系统下的samba服务配置
    第一步安装samba服务apt install -y samba创建一个组,和一个用户,把用户添加到组里面sudouseradd-mtest1\\创建一个名为test1的用户sudouseradd-mtest2\\创建一个名为test2的用户sudogroupaddmanager1\\创建一个名为manager1的组sudogroupaddmanager2m......
  • Ubuntu搭建Samba服务
    Ubuntu搭建Samba服务使用samba​服务可以跨系统的进行文件共享,安装samba​服务的步骤如下:安装步骤安装基础软件sudoapt-getinstallsambasudoapt-getinstallsmbclient#验证安装samba-V目录配置使用编辑器打开配置文件,以vim​​为例sudovim/etc/samba......