1 条题解
-
0
题解:炸弹连锁引爆计数
问题转化
每个炸弹 可以引爆坐标在 内的所有炸弹。
$$\sum_{i=1}^N (i \times \text{cnt}_i) \bmod (10^9+7) $$
初始引爆 后,所有被直接或间接引爆的炸弹都会爆炸,要求对每个 求出引爆的炸弹总数,然后计算:其中 是炸弹 能引爆的总炸弹数。
关键观察
1. 引爆的传递性
如果炸弹 能引爆 , 能引爆 ,那么 也能引爆 。
因此,引爆关系构成一个有向图( 向所有在 内的 连边),需要求每个点能到达的点数。2. 区间合并
由于坐标递增,引爆区间 可能不是单调的,但传递引爆相当于:
- 从 出发,能引爆的炸弹形成一个连续区间 (按坐标排序后的编号区间)。
- 证明:若 能引爆 和 (),且坐标在 和 之间的炸弹 必然在 的覆盖范围内,通过连锁反应也会被引爆。
因此问题变为:对每个 ,求最小的 和最大的 ,使得从 出发能覆盖到 到 的所有炸弹。
3. 递推关系
设 为从 出发能引爆的最左边炸弹编号, 为最右边编号。
初始:,。但实际引爆还会扩展:
如果 能引爆 ,那么 的引爆区间会扩展到 。
因此需要迭代扩展:4. 优化扩展过程
这是一个区间最值扩展问题,可以用单调栈+倍增优化。
定义:
- :从 出发,扩展 步后能到达的最左编号
- :从 出发,扩展 步后能到达的最右编号
初始:
L[i][0] = \text{lower_bound}(X_i - R_i) R[i][0] = \text{upper_bound}(X_i + R_i) - 1递推:
$$L[i][k] = \min_{j \in [L[i][k-1], R[i][k-1]]} L[j][k-1] $$$$R[i][k] = \max_{j \in [L[i][k-1], R[i][k-1]]} R[j][k-1] $$5. 快速求区间最值
由于 可达 ,需要 查询区间最值。
用 ST 表预处理 和 的区间最小值/最大值。设 为 在区间 的最小值, 类似。
那么:
$$L[i][k] = \min_{j \in [L[i][k-1], R[i][k-1]]} L[j][k-1] $$可以用 ST 表 查询。
6. 算法步骤
- 读入 和 ,坐标严格递增。
- 预处理 ST 表,用于查询任意区间 的 最小值和 最大值。
- 初始化 和 :
- 最小的 满足 (二分查找)
- 最大的 满足 (二分查找)
- 倍增迭代 次:
- 对于 到 :
- 对于每个 ,用 ST 表查询 的 最小值作为
- 用 ST 表查询 的 最大值作为
- 对于 到 :
- 计算最终 和 :
- 初始 ,
- 从 向下到 :
- 用 和 查询区间 的 最小值 和 最大值
- 如果 或 ,则更新 ,,并继续
- 最终引爆数
- 计算答案:$$\text{ans} = \sum_{i=1}^N (i \times cnt_i) \bmod (10^9+7) $$
7. 复杂度分析
- 预处理 ST 表:
- 二分查找初始区间:
- 倍增迭代:
- 总复杂度:
- 空间复杂度:
8. 注意事项
- 坐标和半径很大,用
long long存储 - ST 表查询区间最值时注意边界
- 最终答案取模
- 1
信息
- ID
- 6065
- 时间
- 2800ms
- 内存
- 512MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者