概念
分桶法(bucket method)是把一排物品或者平面分成桶,每个桶分别维护自己内部的信息,以达到高校计算的目的的方法。
其中,平方分割(sqrt decomposition)是把排成一排的n个元素每n(1/2)分在一个桶内进行维护的方法的总称。这样的分割方法可以使对区间操作的复杂度降至O(n(1/2))
和线段树一样,根据维护的数据的不同,平分割可以支持很多不同的操作。
1.基于平方分割的RMQ(区间最小值查询)
给定一个数列a1,a2,…,an,目标是在O(n(1/2))的复杂度内实现以下两种功能。
- 求区间[s,t]的最小值
- 给定i,x,把ai的值变为x
2.基于平方分割的RMQ的预处理
令b=floor(n(1/2)),把a中的元素每b就分为一个桶,并且计算出每个桶内的最小值。
3.基于平方分割的RMQ的查询
- 如果桶完全包含在区间内,则查询桶的最小值。
- 如果元素所在的桶不完全被区间包含,则逐个检查最小值。
它们的最小值就是区间的最小值了。
4.基于平方分割的RMQ的值的更新
在更新元素的时候,需要更新该元素所在的桶的最小值。这时候只需要遍历一边桶内的元素就好了。
基于平方分割的RMQ的复杂度
在更新值得时候,因为每个桶内有b个元素,所以复杂度是O(b)=O(n(1/2))
而在查询时
- 完全包含在区间内的桶的个数是O(n/b)
- 所在的桶不被区间完全包含的元素是O(b)
例题: K-th Number POJ 2104
因为查询的个数m很大,朴素的球阀无法在规定时间内求出解,因此应该选用合理的方式维护数据来进行高效的查询。
如果x是滴k个数,那么一定有
- 在区间中不超过x的数不少于k个
- 在区间中小于x的数有不到k个
因此,如果可以快速求出区间中不超过x的数的个数,就可以通过对x进行二分搜索求出第k个数是多少。
接下来,我们可以看一下如何计算某个区间里不超过x的数的个数,如果不进行预处理,那么只能遍历一遍所有的元素。
另一方面,如果区间是有序的,那么就可以通过二分搜索法高效地求出不超过x的数的个数了。
首先,我们看如何使用平方分割来解决这个问题,把数列每b个一组分到各个桶内,每个桶内保存有排序后的数列,这样,如果要求在某个区间中不超过x的数的个数,就可以这样求得。 - 对于完全包含在区间内的桶,用二分搜索法计算。
- 对于所在的桶不完全包含在区间内的元素,逐个检查。