题解 CF1045G【AI robots】
题意
有 $n$ 个人,每个人三个属性 $x_i,r_i,q_i$。两个人 $i,j$ 可以互相看到当且仅当 $x_i\in[x_j-r_j,x_j+r_j],x_j\in[x_i-r_i,x_i+r_i],|q_i-q_j|\le k$。求有多少对人会互相看到。
$1\le n\le 10^5$,$0\le k\le 20$。
思路
神秘波特题,写一个波特题解。本题解为口胡,若有错误或想复杂了请指出。
先离散化。枚举波特 $i$,求有多少合法的波特 $j$。
把每个波特 $i$ 放到第 $q_i$ 个 vector 中,枚举 $q_j$,对每个合法 $q_j$ 二分出对应它的 vector 中 $x_j\in[x_i-r_i,x_i+r_i]$ 的区间。
这个区间内的数满足了限制 $2,3$,考虑有多少个区间里的 $j$ 满足 $x_i\in[x_j-r_j,x_j+r_j]$。转化为点对序列 $(x_j-r_j,x_j+r_j)$,求区间内有多少点 $(a,b)$ 满足 $a\le x_i\le b$。经典转化:相当于对区间内所有 $(a,b)$ 执行区间 $[a,b]$ 加一之后 $x_i$ 位置的值。扫描线,可以差分为前缀 $[1,r]$ 和前缀 $[1,l-1]$ 时的 $x_i$ 位置的值相减。
这样时间复杂度是 $O(nk\log n)$ 的。看起来不太好。
考虑优化,二分部分,每个序列 $q_j$ 二分的值是一样的。把所有二分的值取出来排个序再挂回序列上询问,进行归并即可求出每个值在询问序列上的前驱后继。
扫描线部分,我们执行了 $O(n)$ 次区间加和 $O(nk)$ 次单点求值。考虑不使用树状数组而使用分块。这样可以做到 $O(n\sqrt n+nk)$,略优秀一些。不妨考虑迭代分块,将整块打标记和散块暴力加再分别用分块维护。这样可以做到 $O(n\sqrt[4]n+nk)$。事实上,迭代分块可以做到 $O(n^{1+eps})$ 修改 $O(1)$ 查询。
最终时间复杂度 $O(n\sqrt[4]n+n\log n+nk)$。
本题解为口胡,无代码,若有错误或想复杂了请指出。

浙公网安备 33010602011771号