分段树的构建

时间:2016-02-15 20:26:10

标签: c++ algorithm data-structures segment-tree

给定n个元素的整数数组A和m查询每个查询包含一个整数x我必须回答小于x的数组中的元素数。     0< A [i]< 10 ^ 6&& x< 10 ^ 6

示例:

A [] = {} 105,2,9,3,8,5,7,7

查询

6

8

104

答案

3

5

7

说明:

对于query1元素是= {2,3,5}

对于query2元素是= {2,3,5,7,7}

对于query3元素,

是= {2,9,3,8,5,7,7}

问题:

如何使用分段树来解决这个问题?(我已经建立了分段树来查找范围内的最大值,分钟数和总和但我的想法是空白如何为此构建分段树)。请用示例解释

注意:我已经知道使用排序和二进制搜索的nlogn解决方案(对于每个查询)。我想了解如何利用分段树来解决这个问题。

谢谢

2 个答案:

答案 0 :(得分:0)

如果为数组 A构建分段树,我认为它不会起作用。您可以使用一些启发式/修剪使用段的最大值和最小值,但最后用于

之类的情况
0, 10^6, 0, 10^6, 0, 10^6,...

查询将退化为O(n),因为您需要在每一片叶子中删除。

你应该做的是在可能值的范围上构建一个分段树:对于每个值0<a<10^6,你要记住有多少具有此值的元素在数组中{{ 1}}。例如

A

出现的数组将是

A=[5,2,3,3,3,5,7,7] 

现在查询数组f=[0,0,1,3,0,2,0,1,0,...] 元素数的次数小于A,转换为元素总和的查询来自x直到f的出现数组0中的

您可以使用细分树来回答此查询。

但是,如果您在查询之前知道整个数组 - 这是一个非常无聊的情况 - 您可以使用数组x上的prefix sum预处理时间f和查询时间O(n)

如果数组O(1)的查询和更新是交错的,则段树只会很有用。

如果查询和更新是交错的,我建议使用Fenwicktree,它不像分段树那样灵活,但它是针对这类问题而量身定制的。它更容易实现,更快,并且需要更少的内存。

答案 1 :(得分:0)

使用普通的段树无法在O(logn)中回答此类查询。 您需要使用小波树(也很少有其他数据结构可以回答此查询,但小波树最有趣)。如果您不知道以下数据结构,则此链接可能会有所帮助:

https://codeforces.com/blog/entry/52854

https://youtu.be/4aSv9PcecDw