【笔记】子序列问题
对于序列 ,我们称 为 的子序列,当且仅当存在 使得 并且 。
一个序列的子序列有 种,非空子序列有 种。
子序列的子序列有 种,子序列的子序列的子序列有 种,依次类推。
[Ynoi2015] 盼君勿忘#
每次询问一个序列所有子序列去重后的权值和之和。
考虑对每个权值算贡献,即有多少个子序列包含这个权值,简单容斥下就是 个,所以贡献就是 。
例题#
给定一个子序列,求有多少个本质不同子序列。
定义 表示以 结尾的本质不同子序列数,显然有 ,其中 是在 前面第一次出现。直接转移可以做到 。
事实上我们有更优的容斥方法,定义状态 表示前 个位置有多少个本质不同的子序列数。
考虑从 ,显然第 位可选可不选,所以 ,其中 表示 前面第一个和 相同的位置。时间复杂度为 。
【模板】子序列自动机#
子序列自动机相对于子序列,好比后缀自动机相对与字符串,回文自动机相对与回文串。
我们观察例题的两种方法,找到二者的本质相同之处。
不难发现如果我们对于所有 使得 是在 之后第一次出现,连一条 的边,那么我们就会得到一个有向无环图,即子序列自动机。
所以自动机中的一条路径与一个子序列一一对应,本质不同的子序列数就是路径数。
对于例题的第一种方法, 表示以 为终点了路径数,对于第二种方法表示前 个点的路径数,这样就很清晰是正确的。
例2 Distinct Subsequences#
求所有子序列的本质不同子序列个数之和。
显然就是求所有子序列的子序列自动机中路径条数。
所以我们可以定义状态 表示以 结尾的所有子序列中,所有以 结尾的路径之和,那么 之后任意选,答案为 。
我们枚举 进行转移,其中区间 中等于 的位置不能选,其余位置任选,所以 , 表示区间 中不等于 的位置。
直接转移可以做到 ,事实上我们发现在从小到大枚举 的过程中,对于 后面的 的位置,相当于统一 ,打个标记即可。这样就可以做到线性。
作者:7KByte
出处:https://www.cnblogs.com/7KByte/p/15359993.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效