Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 如何找到从l到r的已排序子数组的第k个元素的和?_Algorithm_Sorting_Sum_Dynamic Programming - Fatal编程技术网

Algorithm 如何找到从l到r的已排序子数组的第k个元素的和?

Algorithm 如何找到从l到r的已排序子数组的第k个元素的和?,algorithm,sorting,sum,dynamic-programming,Algorithm,Sorting,Sum,Dynamic Programming,问题: 我们已经给出了一个大小为N的数组A[]。现在我们给出了Q查询,每个查询由三个整数l,r,k组成,其中: 1<=l<=r<=N 1<=k<=(r-l+1) 1<=N,Q<=10^5 1一种方法是使用mergesort进行预处理,并修改为保留所有已排序中间结果的副本 此预处理需要O(nlogn) 假设我们从32个元素开始。我们现在可以: 16个已排序的2个元素列表 8个已排序的4个元素列表 4个排序的8个元素列表 2个排序的16个元素列表 1已排

问题:
我们已经给出了一个大小为
N
的数组
A[]
。现在我们给出了
Q
查询,每个查询由三个整数
l,r,k
组成,其中:

1<=l<=r<=N
1<=k<=(r-l+1)
1<=N,Q<=10^5

1一种方法是使用mergesort进行预处理,并修改为保留所有已排序中间结果的副本

此预处理需要O(nlogn)

假设我们从32个元素开始。我们现在可以:

  • 16个已排序的2个元素列表
  • 8个已排序的4个元素列表
  • 4个排序的8个元素列表
  • 2个排序的16个元素列表
  • 1已排序的32个元素列表
我们还可以预先计算O(nlogn)中每个列表的前缀和

然后,当面对从l到r的查询时,我们可以识别预处理列表的日志(n),这些日志(n)将一起覆盖从l到r的所有元素

然后,我们可以使用二进制搜索来查找值,以便在已识别的列表中正好有k个较小的元素,并使用前缀和来计算和。

如果O(Q)>=O(logn):

按元素的排序顺序对原始数组索引进行排序,例如:

values:  [50, 10, 20, 40, 30] -> [10, 20, 30, 40, 50]
indices: [#0, #1, #2, #3, #4] -> [#1, #2, #4, #3, #0]
然后,对于每个查询,从左到右扫描排序后的索引,并添加索引在范围([l,r])内的第一个
k
元素的值。复杂性将是O(QN+nlogn)=O(QN)——同样,假设O(Q)>=O(logn)


有一种方法可以改进这一点,首先对查询范围进行排序,然后在对已排序索引的一次扫描中执行所有查询,但如果不了解范围长度的特殊情况,则无法预测这将如何影响复杂性。

对于时间高效的解决方案,尝试使用动态programming@SauravSahu如何使用动态规划实现它?可以在nlogn+qlogn中使用段树(脱机)通过使用其r值对查询进行排序来解决。您可以从中了解段树。相关:请用一些伪代码详细说明查询部分