1 条题解

  • 0
    @ 2025-10-27 22:50:27

    题意理解

    我们有 NN 个天线,第 ii 个天线高度为 HiH_i,它只能向距离在 [Ai,Bi][A_i, B_i] 内的天线发送信息。 如果天线 iijj 可以互相通信(即 ij[Ai,Bi]|i-j| \in [A_i,B_i]ij[Aj,Bj]|i-j| \in [A_j,B_j]),则它们的通信成本为 HiHj|H_i - H_j|

    给定 QQ 个询问 [Lj,Rj][L_j, R_j],问区间内所有天线对中,能互相通信的最大成本是多少,若没有则输出 1-1


    第一步:直接暴力思路

    最直接的方法是枚举所有 i<ji < j,检查它们是否能互相通信,然后计算 HiHj|H_i - H_j|,取最大值。 检查条件为:

    ijAi|i-j| \ge A_iijBi|i-j| \le B_i

    ijAj|i-j| \ge A_jijBj|i-j| \le B_j

    即:

    AijiBiAjjibjA_i \le j-i \le B_i 且 A_j \le j-i \le b_j

    对于询问 [L,R][L,R],只考虑 i,j[L,R]i,j \in [L,R]

    复杂度:O(N2)O(N^2) 对每对天线,再乘 QQ 会超时。

    第二步:固定一个天线,考虑它能和谁通信

    对于天线 ii,它能发送信息的天线 jj 必须满足:

    i+Aiji+Bii+A_i≤j≤i+B_i ​

    并且 jj 能接收 ii 的信号需要满足:

    jBjijAjj−B_j≤i≤j−A_j ​

    所以 (i,j)(i,j) 能互相通信的条件是:

    $$\begin{cases} i + A_i \le j \le i + B_i \\ j - B_j \le i \le j - A_j \end{cases} $$

    第三步:转化为二维数点问题

    我们可以把问题看作:每个天线 ii 对应一个“事件”,询问区间 [L,R][L,R] 内所有满足互相通信条件的天线对 (i,j)(i,j) 的最大 HiHj|H_i - H_j|

    这类区间最值问题常用扫描线 + 线段树/树状数组解决。


    关键观察

    对于一对 (i,j)(i,j)HiHj=max(HiHj,HjHi)|H_i - H_j| = \max(H_i - H_j, H_j - H_i)。 因此我们可以分别考虑两种情况:

    HiHjH_i \ge H_j,则成本 =HiHj= H_i - H_j

    HjHiH_j \ge H_i,则成本 =HjHi= H_j - H_i

    所以问题变成:对于所有合法 (i,j)(i,j),求 max(HiHj,HjHi)\max(H_i - H_j, H_j - H_i)

    第四步:离线处理 我们可以对询问按右端点排序,从左到右扫描 jj,维护之前所有 ii 的信息。

    对于固定的 jj,哪些 ii 能与之互相通信?

    条件:

    $$\big( i \in [j - B_j, j - A_j] \big) \ \land\ \big( j \in [i + A_i, i + B_i] \big) $$

    第一个条件给出了 ii 的范围,第二个条件是对 ii 的限制,可以看作 ii 在插入时带有生效区间 [i+Ai,i+Bi][i+A_i, i+B_i]

    第五步:扫描线 + 线段树维护 我们按 jj 从小到大扫描:

    jj 进入 ii 的生效区间 [i+Ai,i+Bi][i+A_i, i+B_i] 时,将 ii 加入数据结构。

    jj 离开 ii 的生效区间(j>i+Bij > i+B_i)时,将 ii 移除。

    对于每个 jj,我们查询区间 [jBj,jAj][j-B_j, j-A_j] 内的所有 ii,计算 HjHiH_j - H_i(当 HjHiH_j \ge H_i)或 HiHjH_i - H_j(当 HiHjH_i \ge H_j)的最大值。


    具体实现方法

    我们需要维护两种信息:

    对于 HjHiH_j \ge H_i,求 HjHiH_j - H_i 最大 → 即求区间内 HiH_i 的最小值。

    对于 HiHjH_i \ge H_j,求 HiHjH_i - H_j 最大 → 即求区间内 HiH_i 的最大值。

    因此我们可以用两棵线段树:

    一棵维护区间 HiH_i 最大值

    一棵维护区间 HiH_i 最小值

    当扫描到 jj 时:

    [jBj,jAj][j-B_j, j-A_j] 区间内,用 HjminHiH_j - \min H_i 更新答案(如果 min\min 存在且 HjminH_j \ge \min

    maxHiHj\max H_i - H_j 更新答案(如果 max\max 存在且 maxHj\max \ge H_j

    第六步:处理互相通信条件 注意:我们上面只考虑了 jjii 的范围限制 [jBj,jAj][j-B_j, j-A_j],而 iijj 的限制 [i+Ai,i+Bi][i+A_i, i+B_i] 是通过扫描线加入/移除 ii 来保证的。

    这样我们确实覆盖了互相通信的两个条件。

    第七步:算法流程

    离线所有询问,按 RR 排序。

    准备两个线段树:seg_max 和 seg_min,初始值设为 -\infty++\infty

    准备事件:

    对于每个 ii,在 j=i+Aij = i+A_i 时将 ii 插入数据结构

    j=i+Bi+1j = i+B_i+1 时将 ii 移除

    j=1Nj=1 \dots N 扫描:

    处理所有在 jj 时刻加入的 ii,更新线段树位置 iiHiH_i

    处理所有在 jj 时刻移除的 ii,更新线段树位置 ii 为无效值

    对于所有 Rj=jR_j = j 的询问 [L,j][L, j]

    在区间 max(L,jBj),jAjmax(L, j-B_j), j-A_j 内(如果区间有效)查询 minH 和 maxH

    HjminHH_j - minHmaxHHjmaxH - H_j 更新该询问的答案

    输出每个询问的最终答案(若未更新则输出 1-1

    第八步:复杂度

    每个 ii 加入/移除一次:O(N)O(N) 次操作

    每个询问查询一次:O(Q)O(Q) 次操作

    线段树操作 O(logN)O(\log N)

    总复杂度 O((N+Q)logN)O((N+Q)\log N),可过。


    公式总结

    互相通信条件:

    max(Ai,Aj)jimin(Bi,Bj)max(A_i,A_j) \le j-i \le min(B_i,B_j)

    成本:

    cost(i,j)=HiHj=max(HiHj,HjHi)cost(i,j)=|H_i-H_j|=max(H_i-H_j,H_j-H_i)

    扫描线维护:

    加入事件:j=i+Aij = i + A_i 时加入 ii

    移除事件:j=i+Bi+1j = i + B_i + 1 时移除 ii

    查询区间:i[jBj,jAj]i \in [j - B_j, j - A_j]

    这样我们就得到了一个高效的 O((N+Q)logN)O((N+Q)\log N) 解法。

    • 1

    信息

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