P5025 [SNOI2017] 炸弹

题目描述

在一条直线上有 n 个炸弹,每个炸弹的坐标是 xi​,爆炸半径是 ri​,当一个炸弹爆炸时,如果另一个炸弹所在位置 xj​ 满足: ∣xj​−xi​∣≤ri​ ,那么,该炸弹也会被引爆。

现在,请你帮忙计算一下,先把第 i 个炸弹引爆,将引爆多少个炸弹呢?

答案对 109+7 取模。

输入格式

第一行,一个数字 n ,表示炸弹个数。 第 2∼n+1 行,每行两个整数,表示 xi​,ri​,保证 xi​ 严格递增。

输出格式

一个数字,表示 i=1∑n​i× 炸弹 i 能引爆的炸弹个数。

输入输出样例

输入 #1

复制代码
4
1 1
5 1
6 5
15 15

输出 #1

复制代码
32

说明/提示

【数据范围】

对于 20% 的数据: n≤100。

对于 50% 的数据: n≤1000。

对于 80% 的数据: n≤100000。

对于 100% 的数据: 1≤n≤500000,−1018≤xi​≤1018,0≤ri​≤2×1018。

题解

cpp 复制代码
#include <cstdio>
#include <iostream>
const int nn = 5e5 + 5, mod = 1e9 + 7;
int n, l[nn], r[nn];
long long ans, a[nn], range[nn];
int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%lld %lld", a + i, range + i);
        l[i] = r[i] = i;
    }
    for (int i = 2; i <= n; i++) {
        while (l[i] > 1 && a[i] - a[l[i] - 1] <= range[i]) {
            range[i] = std::max(range[i], range[l[i] - 1] - (a[i] - a[l[i] - 1]));
            l[i] = l[l[i] - 1];
        }
    }
    for (int i = n - 1; i >= 1; i--) {
        while (r[i] < n && a[r[i] + 1] - a[i] <= range[i]) {
            l[i] = std::min(l[i], l[r[i] + 1]);
            r[i] = r[r[i] + 1];
        }
    }
    for (int i = 1; i <= n; i++)
        ans = (ans + 1ll * i * (r[i] - l[i] + 1)) % mod;
    printf("%lld\n", ans);
    return 0;
}

无论如何引爆,如果炸弹 l 和 r 被引爆了 (l≤r),那么任何炸弹 p∈l,r 都会被引爆。那么考虑维护最开始引爆炸弹 i 后,所有最后被引爆的炸弹区间 li​,ri​。

先把所有 li​,ri​ 初始化为 i,i,然后令 i 从 2 开始,到 n 结束,执行以下操作:

  • 判断自己能否引爆炸弹 li−1,如果不能或者 li=1,终止操作
  • 比较自己的爆炸右边界 (xi+rangei) 与 li−1 的爆炸右边界 (xli−1+rangeli−1),如果后者更大那么用后者减去 xi 的值来更新 rangei
  • 将 li 更新为 lli−1,并返回第一个操作

这样一轮算下来之后我们就可以计算出只往左爆炸能够到达的边界 li​,时间复杂度是线性的

(创作不易,感谢点赞,原创切勿抄袭,抄袭可耻)

相关推荐
A boy CDEF girl1 小时前
算法题专栏:优选算法
数据结构·算法·leetcode
没落之王1 小时前
三易五行看宋朝的三界确立
大数据·人工智能·算法
wuminyu2 小时前
Java字节码学习总结:字节码如何加载、解析和执行
java·linux·c语言·jvm·c++
qq_406981032 小时前
c++的decltype是什么
开发语言·c++
坤坤子吖2 小时前
算法学习——单调队列
开发语言·c++·笔记·学习·算法
杜 硕2 小时前
从零开始的C++生活——第六讲——01
开发语言·c++·生活
Js.Tx3 小时前
【具体数学 Concrete Mathematics】2.1.5 一般性的方法
算法·具体数学
Risehuxyc5 小时前
C++(VS2026)使用Ncap库的配置
c++
秋天的怀念_David5 小时前
算法一千零一夜 · 作品相关:版权与致谢声明
程序人生·算法·学习方法