1 条题解

  • 0
    @ 2025-10-19 20:52:24

    题意简述 给定长度为 N 的数组 c,Q 次询问,每次问区间 [L, R] 内最多能选出多少个不相交的、和为 0 的连续子数组。

    解法 前缀和转化 设 sum[i] 为前缀和,子数组 [l, r] 和为 0 等价于 sum[r] = sum[l-1]。

    贪心匹配 从左到右扫描,对于每个右端点 i,找它前面最近的一个左端点 j 使得 sum[j] = sum[i] 且 j 未被使用,这样匹配不会影响后续匹配数。

    离线处理 将询问按右端点排序(或按左端点倒序),用树状数组维护当前可用的子数组区间。

    DFS 序 + 树状数组 将每个和为 0 的子数组看作节点,建立包含关系的树结构,DFS 序映射后,一个区间 [L, R] 内能选出的子数组数就是某个 DFS 区间内的节点数,用树状数组维护。

    时间复杂度 离散化:O(N log N)

    贪心匹配:O(N)

    树状数组查询:O((N+Q) log N)

    总复杂度:O((N+Q) log N),可过 4×10^5 数据。

    代码关键点 dfn[i] 表示以 i 结尾的最短和为 0 子数组的左端点。

    通过 head[] 和 nxt[] 模拟邻接表建立区间包含树。

    树状数组在 DFS 序上做区间加、单点查询,统计覆盖数。

    • 1

    信息

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