sqrt分解输入查询

时间:2016-08-18 16:28:03

标签: algorithm data-structures

我在此网站上了解了sqrt分解数据结构https://acmcairoscience.wordpress.com/2015/04/06/sqrt-decomposition/

我已经理解了这个DS的标准算法,我们将输入数组划分为大小为sqrt(N)的桶,其中N是数组的大小。

但这是我无法理解的:输入查询的sqrt分解。

假设我们遇到一些问题,我们会给出一些输入数据,然后是k个查询,我们每个查询都需要处理并发出响应。我们考虑请求是按请求(不改变系统状态,但仅询问某些信息)和修改(即影响系统状态最初设置为输入数据)的情况。

这是我无法理解的给定方法:在大小为sqrt(k)的桶中拆分k个查询,并立即处理每个桶中的所有查询。

为什么我们将查询分解为sqrt大小的存储桶?以及我们如何处理每个桶中的所有查询?

2 个答案:

答案 0 :(得分:0)

他没有将查询拆分为存储桶,而是将数据逻辑拆分为sqrt(k)的存储桶。然后,他不是在接收到每个查询时回复,而是重新排序查询,以便按范围按顺序处理它们。也就是说,在桶N中开始的查询在桶N + 1中开始的查询之前处理,而在桶M中结束的查询在桶M + 1中结束的查询之前处理。

因此,查询按从左到右的顺序进行处理。

如果有sqrt(n)个桶,则每个桶的大小为sqrt(n)。让我们说q = sqrt(n)。

让我们说第一个查询只使用存储桶1.程序必须为第一个存储桶执行aq ^ 2计算然后缓存结果,以便任何其他查询启动在桶1中不再需要进行计算。当程序从左到右处理查询时,它最终必须对每个桶执行相同的q ^ 2计算。如果查询最终使用了所有桶,那么我们进行q计算,每次计算花费q ^ 2次。

由于q = sqrt(n),则q * q ^ 2 = sqrt(n)* n。

答案 1 :(得分:0)

像其他任何好主意一样,在某些特殊情况下执行查询查询也是如此。 整个过程与一堆查询有关,您将使用两个指针最多想到整个数组。

所以这个的必要条件是  -如果我们有段[l,r]的答案,我们可以轻松获得[l。 r + 1],[l + 1,r],[l,r-1]

如何证明sqrt(Q)* k时间复杂度。

-let首先假设您可以在以下位置得到这些段的答案([l。r + 1],[l + 1,r],[l,r-1] ) O(1)给出段 [l,r] 的答案 -由于每个查询桶的左侧按任意顺序排列,但右侧排序,因此对于存储桶中的每个查询,我们都可以通过向左移动指针来进行O(存储桶长度)迭代,但是对于右侧,只能将其增加整个存储桶中,我们只能向右移一次到数组末尾。