1 条题解
-
0
题意简述 给定长度为 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
- 上传者