不同数字及其数量的乘积之和

时间:2015-03-04 17:24:20

标签: algorithm data-structures

给定N个元素的数组,其中N最多为200000.数组元素最大为100000.现在我们提供形式为[a b]的Q查询。对于每个查询,我们需要告诉总和:

((Count of each distinct number in range a to b)^2)*(Value of that distinct number)

示例令N = 8且数组为[1 1 2 2 1 3 1 1],并且令Q = 1。这意味着只需一个查询。设a = 2且b = 7,则答案为20

解释

occurrence of 1-> 3
occurrence of 2-> 2
occurrence of 3-> 1
cost=3*3*1 + 2*2*2 + 1*1*3= 20

现在,如果查询的次数少于不那么困难的问题,那么Q可以达到200000.那么这个问题最适合的数据结构是什么?

1 个答案:

答案 0 :(得分:2)

此处离线O((n + q) * sqrt(n))解决方案:

  1. 让我们将给定的数组分成sqrt(n)个连续的块,每个块都有sqrt(n)个元素。

  2. 让我们根据包含左边框的数字划分所有查询。

  3. 现在我们将分别回答每个小组的查询:

    • 在一个组中,我们应按其右边界(按递增顺序)对查询进行排序。

    • 让我们按排序顺序迭代来自该组的所有查询,并保持以下不变量:除了可能是第一个和最后一个块之外,位于该查询所涵盖的块内的所有数字都已处理完毕。我们可以通过在需要时处理下一个块来维护它。

    • 鉴于此不变量,我们可以通过仅查看第一个和最后一个块(包含此查询的边框)中的数字来获得此查询的答案。最多O(sqrt(n))个这样的数字,所以我们可以简单地迭代它们。

    • 澄清:我们维护一个大小为count的数组MAX_VALUE,其中count[i]是已处理数字中i的出现次数{{1} - 处理过的数字的目标函数之和。我们可以在curSum中添加或删除一个数字:递增或递减O(1)并调整count[i]。已处理的数字表示已在curSum数组和count变量中考虑该数字。

  4. 时间复杂度:对于每个组,我们一次从左到右遍历数组以处理内部块中的数字。这需要curSum次。每个查询都为处理此查询的第一个和最后一个块中的数字提供了额外的O(n * sqrt(n))时间。因此,总时间复杂度为O(sqrt(n))