1 条题解
-
0
「子序列计数」题解
题意简化
给定字符串 ,字符集大小为 ,多次询问区间 内本质不同子序列的数量(不含空序列)。
。核心观察
1. 经典DP公式
设 表示前 个字符的本质不同子序列数(包含空序列)。
$$dp[i] = 2 \times dp[i-1] - dp[\text{last}[s[i]] - 1] $$
转移:其中 是字符 上一次出现的位置。
解释:
- :每个旧子序列可以选择是否加上
- 减去 :减去上次出现时已经计算过的重复子序列
最终答案(不含空序列)为 。
2. 区间查询问题
我们需要对任意区间 计算答案。
设 表示 的子序列数(包含空序列)。
从 开始做同样的 DP,但 需要基于区间 重新计算。关键思路:矩阵乘法 + 前缀积
1. 矩阵表示
考虑字符集大小 。
将 DP 过程用矩阵表示,状态向量包含 个值:
,其中 表示以字符 结尾的子序列数。处理字符 时:
- 新的
- 新的
- 其他 不变
对应一个 的转移矩阵 。
2. 区间查询转化为矩阵乘法
对于区间 :
$$\text{答案向量} = \text{初始向量} \times M_{s[l]} \times M_{s[l+1]} \times \dots \times M_{s[r]} $$初始向量为 (只有空序列)。
3. 快速查询
预处理前缀矩阵积:
则区间 的矩阵积为:
由于 ,矩阵只有 ,求逆和乘法都是 。
算法步骤
-
预处理转移矩阵
- 对每个字符 ,构造对应的
- 计算前缀积
- 同时计算前缀积的逆
-
回答查询 对每个询问 :
- 计算
- 初始向量
- 答案 = (去掉空序列)
复杂度
- 预处理:,但 ,实际
- 每次查询:
- 总复杂度:,可过
关键点
- 将 DP 转化为矩阵乘法
- 利用前缀积和逆矩阵快速回答区间查询
- 字符集小()是核心,矩阵操作是常数时间
- 1
信息
- ID
- 6005
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者