数组在给定范围内每个不同整数的出现次数

时间:2019-06-14 20:53:39

标签: algorithm segment-tree

给出n个整数(n <= 1e6) [a0, a1, a2, ... an-1] (a[i] <= 1e9)和多个查询的数组。在每个查询中,给出2l r的整数,我们需要返回该范围内的每个不同整数的计数((0 <= l <= r <= n-1)和{{ 1}})。

我只能想出一个蛮力解决方案来遍历每个查询的整个范围。

l

例如:

r

编辑-我想出了类似的东西,但它的复杂性仍然很高。我认为是因为该插入操作。

d={}
for i in range(l, r+1):
    if arr[i] not in d:
        d[arr[i]]=0
    d[arr[i]]+=1

3 个答案:

答案 0 :(得分:0)

您可以使用here中所述的二进制索引树。与其将范围总和存储在节点中,不如将值到对应范围的计数的映射存储。

现在,使用输入x查询树,以找到一个表示相应索引前缀[1..i]中每个元素的出现频率的映射。这将需要合并O(log n)映射。

现在您可以执行两个查询:一个查询l-1,另一个查询r。从后者“减去”前者结果图。地图减法是入门级的。我会让你弄清楚细节。

每个查询的时间为O(k log n),其中k为地图大小。这最多是输入数组中不同元素的数量。

答案 1 :(得分:0)

听起来这可能是我们安排查询方式的候选者。假设查询的数量和输入的长度都在n的量级上,类似于this post,我们可以根据floor(l / sqrt(n))对它们进行存储,并按r对每个存储区进行排序。现在我们有了sqrt(n)个存储桶。

由于q中的每次移动,每个存储桶的O(q * sqrt(n))查询最多将发生l个变化,而由于{{1}的逐渐变化,最多O(n)个变化}(由于我们按r对每个存储桶进行了排序,因此间隔的这一边只会在处理存储桶时稳定增加)。

处理一个存储桶中所有间隔右侧的更改都绑定到r,我们有O(n)个存储桶,因此sqrt(n)右边。并且由于所有O(n * sqrt(n)的数量为q(假设),并且每个数量最多需要在左侧进行O(n)个更改,因此左侧的更改也为{{1} }。

因此,总时间复杂度为O(sqrt(n)),其中O(n * sqrt(n))是输出的总数。 (更新后的数据结构可以是一个哈希图,该哈希图还允许在其当前存储上进行迭代。)

答案 2 :(得分:0)

您可以使用哈希映射。从l到r进行迭代,并将每个元素存储为键,将出现的次数存储为count。将使用O(n)来指定给定范围内不同元素的数量。每次将元素插入哈希图中时,都必须检查哈希图中是否存在元素。如果元素已经存在,则更新计数,否则将计数保持为1。