洛谷 P4631 - [APIO2018] 选圆圈(类平面最近点对分治法)

洛谷题面传送门

说实话在看题解之前我甚至不会复杂度低于平方的算法,毕竟我感觉圆覆盖这个东西……挺难用传统 DS 维护的吧(

事实上,如果你会平面最近点对的分治做法,那么你会发现那个做法对此题很有启发式作用。

首先考虑将平面划分成若干个网格状的正方形,具体来说假设当前半径最大的圆的半径为 \(R\),那么我们就将网格划分为 \(2R\times 2R\) 的网格且刚好卡住半径最大的圆,这样我们遍历与一个圆可能相交的圆时,只需检查那些在周围 \(8\) 个区域中的圆即可。当最大圆的半径小于 \(\dfrac{R}{2}\) 时我们就重新划分。考虑这样做的时间复杂度,显然划分的轮数是 \(\log R\) 级别的,而在一轮中每个圆被访问次数是常数级别的,感性理解就是其周围 \(8\) 个格子中不会有太多两两不相交且半径 \(\ge\dfrac{R}{2}\) 的圆。而为了定位到一个圆所在位置需要使用 map,总复杂度 \(n\log n\log R\),把 map 换成哈希表可以做到 \(n(\log n+\log R)\)

posted @ 2022-08-15 19:27  tzc_wk  阅读(68)  评论(0编辑  收藏  举报