1 条题解

  • 0
    @ 2025-11-18 8:24:44

    好的,我们来根据这个代码生成题解和算法标签。


    算法思路

    这是一个 环形 DP + 线段树维护矩阵乘法 的解法。

    问题转化

    题目要求:在一个长度为 nn 的环上选择一些数,不能有连续 44 个或以上的数被选中,求最大和。

    这是一个 环形 DP 问题,但直接做是 O(n)O(n) 的,而 n,qn, q 可达 4×1044\times 10^4,需要支持修改,所以必须优化。


    状态设计

    fi,jf_{i, j} 表示考虑前 ii 个位置,末尾连续选择了 jj 的最大和(j=0,1,2,3j = 0,1,2,3)。

    转移:

    • 如果第 ii 个不选:$f_{i, 0} = \max(f_{i-1, 0}, f_{i-1, 1}, f_{i-1, 2}, f_{i-1, 3})$
    • 如果第 ii 个选:
      • fi,1=fi1,0+aif_{i, 1} = f_{i-1, 0} + a_i
      • fi,2=fi1,1+aif_{i, 2} = f_{i-1, 1} + a_i
      • fi,3=fi1,2+aif_{i, 3} = f_{i-1, 2} + a_i

    注意 j=3j=3 时不能再选下一个(否则连续 44 个)。


    矩阵形式

    [fi,0,fi,1,fi,2,fi,3][f_{i,0}, f_{i,1}, f_{i,2}, f_{i,3}] 看作向量,则转移可以写成矩阵乘法:

    $$\begin{bmatrix} f_{i,0} & f_{i,1} & f_{i,2} & f_{i,3} \end{bmatrix} = \begin{bmatrix} f_{i-1,0} & f_{i-1,1} & f_{i-1,2} & f_{i-1,3} \end{bmatrix} \times M_i $$

    其中

    $$M_i = \begin{bmatrix} 0 & a_i & -\infty & -\infty \\ 0 & -\infty & a_i & -\infty \\ 0 & -\infty & -\infty & a_i \\ 0 & -\infty & -\infty & -\infty \end{bmatrix} $$

    这里 -\infty 表示不可达。


    环形处理

    因为是环,我们枚举前 33 个位置的选择情况(即初始向量),然后做一次 1n1 \to n 的矩阵乘法,最后检查末尾状态与初始状态是否冲突(末尾连续选择个数 + 开头连续选择个数 < 4)。

    代码中简化处理:直接枚举末尾状态 ii(0~3),然后取 w[0][j]w[0][j]jij \le i 的最大值,这样隐含了环形约束。


    线段树维护

    线段树每个节点存一个 4×44\times 4 的矩阵,表示该区间上的转移矩阵的乘积。
    修改时更新叶子节点矩阵中的 aia_i,然后向上合并。

    合并就是矩阵乘法(++max\max×\times++)。


    复杂度

    • 初始建树:O(n43)O(n \cdot 4^3)
    • 每次修改:O(logn43)O(\log n \cdot 4^3)
    • 查询:O(43)O(4^3)(直接取根节点)

    代码注释摘要

    • tr[num][i][j] 表示从状态 ii 进入该区间,离开时状态为 jj 的最大值。
    • 叶子矩阵构造:
      • 选一个数:010\to 1, 121\to 2, 232\to 3aia_i
      • 不选:i0i\to 000
    • 查询时枚举环的“断点”状态(末尾状态 ii),取合法值。

    • 1

    「ROIR 2020 Day 2」海报 传统1000 ms256 MiB

    信息

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