1 条题解

  • 0
    @ 2025-12-10 16:02:56

    「子序列计数」题解

    题意简化

    给定字符串 ss,字符集大小为 99,多次询问区间 [l,r][l, r]本质不同子序列的数量(不含空序列)。
    n,q105n, q \le 10^5

    核心观察

    1. 经典DP公式

    dp[i]dp[i] 表示前 ii 个字符的本质不同子序列数(包含空序列)。
    转移:

    $$dp[i] = 2 \times dp[i-1] - dp[\text{last}[s[i]] - 1] $$

    其中 last[c]\text{last}[c] 是字符 cc 上一次出现的位置。

    解释

    • 2×dp[i1]2\times dp[i-1]:每个旧子序列可以选择是否加上 s[i]s[i]
    • 减去 dp[last1]dp[\text{last}-1]:减去上次出现时已经计算过的重复子序列

    最终答案(不含空序列)为 dp[n]1dp[n]-1

    2. 区间查询问题

    我们需要对任意区间 [l,r][l, r] 计算答案。

    f(l,r)f(l, r) 表示 s[l..r]s[l..r] 的子序列数(包含空序列)。
    ll 开始做同样的 DP,但 last[c]\text{last}[c] 需要基于区间 [l,r][l, r] 重新计算。

    关键思路:矩阵乘法 + 前缀积

    1. 矩阵表示

    考虑字符集大小 m=9m=9
    将 DP 过程用矩阵表示,状态向量包含 m+1m+1 个值:
    [dp,cnt1,cnt2,,cntm][dp, cnt_1, cnt_2, \dots, cnt_m],其中 cntccnt_c 表示以字符 cc 结尾的子序列数。

    处理字符 cc 时:

    1. 新的 dp=2×dpoldcntcdp = 2\times dp_{old} - cnt_c
    2. 新的 cntc=dpoldcnt_c = dp_{old}
    3. 其他 cntccnt_{c'} 不变

    对应一个 (m+1)×(m+1)(m+1)\times(m+1) 的转移矩阵 McM_c

    2. 区间查询转化为矩阵乘法

    对于区间 [l,r][l, r]

    $$\text{答案向量} = \text{初始向量} \times M_{s[l]} \times M_{s[l+1]} \times \dots \times M_{s[r]} $$

    初始向量为 [1,0,0,,0][1, 0, 0, \dots, 0](只有空序列)。

    3. 快速查询

    预处理前缀矩阵积:
    Pi=M1×M2××MiP_i = M_1 \times M_2 \times \dots \times M_i

    则区间 [l,r][l, r] 的矩阵积为:

    Pl11×PrP_{l-1}^{-1} \times P_r

    由于 m=9m=9,矩阵只有 10×1010\times10,求逆和乘法都是 O(1)O(1)

    算法步骤

    1. 预处理转移矩阵

      • 对每个字符 cc,构造对应的 McM_c
      • 计算前缀积 Pi=Pi1×Ms[i]P_i = P_{i-1} \times M_{s[i]}
      • 同时计算前缀积的逆 Pi1P_i^{-1}
    2. 回答查询 对每个询问 [l,r][l, r]

      • 计算 Q=Pl11×PrQ = P_{l-1}^{-1} \times P_r
      • 初始向量 V0=[1,0,,0]V_0 = [1, 0, \dots, 0]
      • V=V0×QV = V_0 \times Q
      • 答案 = V[0]1V[0] - 1(去掉空序列)

    复杂度

    • 预处理:O(n×m3)O(n \times m^3),但 m=9m=9,实际 O(n)O(n)
    • 每次查询:O(m3)=O(1)O(m^3) = O(1)
    • 总复杂度:O(n+q)O(n + q),可过 10510^5

    关键点

    • 将 DP 转化为矩阵乘法
    • 利用前缀积和逆矩阵快速回答区间查询
    • 字符集小(m=9m=9)是核心,矩阵操作是常数时间
    • 1

    信息

    ID
    6005
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者