整体二分

郑哥狂喜

引入:静态区间第 k 小。给定一个数组和若干个询问,每次询问要查询某个区间中第 k 小的数。

这里介绍一种整体二分的算法。

如果只有一个询问,有一种二分的算法:

初始左右端点设为整个数组的最小值和最大值,不断二分。看一下二分值 mid,比 mid 小的数有 t 个。如果 tk,则答案一定在 [l,mid] 中,否则在 [r,mid] 中。

而查询区间内比 mid 小的数的个数,可以用 BIT,把所有小于等于 mid 的都设成 1,大于的设成 0

这么做的时间复杂度是 O(nlognlogC)C 是数的值域。

如果每个询问都这么做,复杂度 O(nqlognlogC) 太慢。考虑对所有询问整体二分,一次性多处理。

定义一个集合 Q 初始包含所有询问,一个集合 A 初始包含数组所有数。

一个函数 solve(l,r,Q,A) 表示当前二分到区间 [l,r]Q 中的询问的答案在 [l,r] 中,A 是原数组中所有值在 [l,r] 中的数的集合。

如果 l=r1,则 Q 中所有询问答案为 l

当执行 solve(l,r,Q,A),取 mid=(l+r)/2,枚举 A 中所有数,如果这个数小于等于 mid,把它的位置在 BIT 上设为 1;否则设为 0

然后枚举 Q 中的询问,利用 BIT 查询它的区间内小于等于 mid 的数的个数 t,如果 tk,就把他放进一个集合 q1;否则放入 q2

同时 A 中小于等于 mid 的放入集合 a1,大于的放入 a2

然后递归 solve(l,mid,q1,a1),solve(mid,r,q2,a2)

posted @   FLY_lai  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示