题解

1 条题解

  • 0
    @ 2023-05-07 12:29:08

    观察:\(|x_i−x_j|+|y_i−y_j|≤C\),发现这个式子和 \(x,y\) 都有关,不便维护

    我们将点 \((x,y)\) 变成 \((a,b)\),其中 \(a=x+y,b=x-y\),那么曼哈顿距离:\(|x_i−x_j|+|y_i−y_j|=max(|a_i−a_j|,|b_i−b_j|)\),推导图下:

    当 \(x_i>=x_j\) 且 \(y_i>=y_j\) 时,\(|x_i−x_j|+|y_i−y_j|= x_i−x_j+y_i−y_j = (x_i+y_i)-(x_j+y_j) = a_i−a_j\)
    当 \(x_i>=x_j\) 且 \(y_i<y_j\) 时,\(|x_i−x_j|+|y_i−y_j|= x_i−x_j-y_i+y_j = (x_i-y_i)-(x_j-y_j) = b_i−b_j\)
    当 \(x_i<x_j\) 且 \(y_i>=y_j\) 时,\(|x_i−x_j|+|y_i−y_j|= x_j−x_i+y_i−y_j = (x_j-y_j)-(x_i-y_i) = b_j−a_i\)

    当 \(x_i<x_j\) 且 \(y_i<y_j\) 时,\(|x_i−x_j|+|y_i−y_j|= x_j−x_i+y_j−y_i = (x_j-y_j)-(x_i+y_i) = a_j−a_i\)

    所以:\(|x_i−x_j|+|y_i−y_j| = max(a_i−a_j,a_j−a_i,b_i−b_j,b_j−a_i)=max(|a_i−a_j|,|b_i−b_j|)\)

    经过上面的转化,我们现在只要保证 \(max(|a_i−a_j|,|b_i−b_j|)≤C\),即 \(|a_i−a_j|≤C且|b_i−b_j|≤C\) 即可。

    因此我们按 \(a[i]\) 从小到大把点排序,然后维护一个滑动窗口,满足窗口中左右端点元素的 \(a\) 之差 \(≤C\)(用双指针维护)。对于 \(i\),先把 \(i\) 作为右端点进进窗口,若 \(a[i]\)与窗口左端点元素的 \(a\) 之差大于 \(C\),则左端点出窗口……。而窗口中的 \(b\) 怎么维护呢?

    维护一棵平衡树存储当前窗口里的所有点的 \(b\),然后对于 \(i\),若最短点要出窗口,则从平衡树中删除……,然后在平衡树里查找 \(b_i\) 的前驱和后继,判断其中是否有一个与 \(b_i\) 差的绝对值 \(<=C\),如果是,就将它们的编号合并(用一个并查集)

    最后在并查集里查找找答案即可!

  • 1

信息

ID
2680
难度
9
分类
数据结构 | 平衡树 点击显示
标签
递交数
3
已通过
1
通过率
33%
被复制
1
上传者