阵列的更新的数组的间隔树

时间:2014-11-09 10:44:37

标签: algorithm time-complexity segment-tree

给定一个大小为N的数组,以及一个大小为N的区间数组,每个区间都是第一个数组的连续段,我需要处理更新数组元素并要求总和的Q查询第二个数组中的段(iTH间隔中的元素与jTH间隔的总和)。

现在,可以轻松处理第一个查询。我可以从数组中构建一个分段树。我可以用它来计算第一个数组中间隔的总和(第二个数组中的一个元素)。但是如何处理O(log n)中的第二个查询?在最坏的情况下,我更新的元素将在第二个数组的所有间隔中。

我需要一个O(Q log N)或O(Q (logN)^ 2)解决方案。

1 个答案:

答案 0 :(得分:0)

这是一个O((Q + N) * sqrt(Q))解决方案(它基于一个非常标准的sqrt分解思路):
1.让我们假设数组永远不会更新。然后问题变得非常简单:使用前缀和,可以在O(N)时间进行预计算和每个查询O(1)解决此问题(这里我们需要2个前缀和数组:一个用于原始数组和另一个用于间隔数组。) 2.现在让我们将查询分成大小为sqrt(Q)的块。在每个块的开头,我们可以执行与1中相同的操作。仅考虑在此块开始之前发生的那些更新。它可以在线性时间内完成(使用前缀和两次)。此类计算的总数为Q / sqrt(Q) = sqrt(Q)次(因为它是我们拥有的块数)。到目前为止,它总共给我们O((N + Q) * sqrt(Q))个时间 3.当我们得到类型2的查询时,已经考虑了当前块之外的所有更新。因此,最多sqrt(Q)次更新可能会影响答案。因此,让我们几乎天真地处理它们:迭代在此查询之前发生的当前块内的所有更新并更新答案。为此,我们需要知道从ij的间隔中数组中给定位置的出现次数。使用O(Q * sqrt(N + Q))时间和空间的扫描线算法可以离线解决此部分(由于可以使用基数排序,因此不会出现额外的对数因子)。

所以我们在最坏的情况下得到O((N + Q) * sqrt(Q))时间和空间。当然,它比O(Q * log N)更糟糕,但对于约10^5个查询和数组元素应该可以正常工作。