题解 CF1045G【AI robots】

$\text{Link}$

题意

有 $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)$。

本题解为口胡,无代码,若有错误或想复杂了请指出。

posted @ 2022-10-21 07:47  ffffyc  阅读(5)  评论(0)    收藏  举报  来源