拟合二维平面中的线段

时间:2017-11-05 12:43:55

标签: algorithm data-structures segment-tree persistent-data

我遇到以下问题的麻烦

  

给定 N x S 网格和 m 段与水平轴平行(所有这些都是元组(x',x'& #39;,y)),回答 Q 表单(x',x'')的在线查询。这种查询的答案是最小的 y (如果有的话),这样我们就可以放置一个段(x',x'',y)。所有段都是非重叠的,但是一段的开头可以是另一段的结尾,即段(x',x'',y)和(x'',x&#39 ;'',y)是允许的。能够放置一个分段意味着可能存在一个不会违反规定规则的分段(x',x'',y),分段实际上并未放置(初始细分未被修改)但我们只声明可能有一个。

约束

1 ≤ Q, S, m ≤ 10^5
1 ≤ N ≤ 10^9

Time: 1s
Memory: 256 Mb

enter image description here

以下是以下链接中的示例。输入段为(2,5,1),(1,2,2),(4,5,2),(2,3,3),(3,4,3)。
回答查询

1)(1,2)→1

2)(2,3)→2

3)(3,4)→2

4)(4,5)→3

5)(1,3)→不能放置一段

第三个查询(蓝色部分)的可视化答案:

A visualized answer for the third query

我不太明白如何解决问题。它应该用持久的分段树来解决,但我仍然无法想出一些东西。

你能帮帮我吗?

这不是我的功课。源问题可以在http://informatics.mccme.ru/mod/statements/view3.php?chapterid=111614找到。这个陈述没有英文版本可用,测试用例以不同的方式显示输入数据,所以不要介意这些。

2 个答案:

答案 0 :(得分:3)

这是一个O(N log N)时间解决方案。

预备(可用的好教程here):分段树,持久分段树。

第0部分。原始问题陈述

我简要描述了原始的问题陈述,因为稍后我会用它的术语而不是抽象的段来说话。

有一个有S座位的火车(S <= 10 ^ 5)。众所周知,座位s_i从时间l_i到时间r_i(不超过10 ^ 5个这样的约束或乘客)被占用。然后我们必须回答10 ^ 5种类型的查询“找到一个座位的最低编号,从时间l_i到时间r_i是免费的,或者说没有”。所有查询都必须在线回答,也就是说,在查看下一个查询之前,您必须回答上一个查询。

在整个文本中,我用N表示座位数,乘客数量和查询数量,假设它们是相同的数量级。如果需要,您可以进行更准确的分析。

第1部分。回答单个查询

让我们回答一个查询[L,R],假设在时间R之后没有占用的位置。对于每个座位,我们保持最后一次占用。最后称呼它(S)。现在查询的答案是最小S,使得last(S)&lt; = L.如果我们在座位上构建段树,那么我们将能够在O(log ^ 2 N)时间内回答该查询:二分搜索S的值,检查段[0,S]上的最小范围是否最多为L。

然而,获得Accepted可能还不够。我们需要O(log N)。回想一下,分段树的每个节点在相应的范围内存储最小值。我们从根本开始。如果最小值为> = L,那么此类查询没有可用的席位。否则,左孩子或右孩子的最小值是&lt; = L(或两者)。在第一种情况下,我们下降到左边的孩子,在第二种情况下 - 向右,然后重复,直到我们到达一片叶子。该叶子将对应于具有最后(S)&lt; = L。

的最小座位

第2部分。解决问题

我们在座位上保持一个持久的树,为每个座位存储最后一个(S)(与前一部分相同)。让我们按照其左端点按递增顺序逐个处理初始乘客。对于乘客(s_i,l_i,r_i),我们使用值r_i更新位置s_i处的分段树。树是持久的,所以我们将新副本存储在某个地方。

要回答查询[L,R],找到最新版本的段树,以便更新发生在R之前。如果对版本进行二进制搜索,则需要O(log N)时间。

在段树的版本中,只有左端点的乘客< R被考虑(甚至更多,正是这样的乘客)。因此,我们可以使用第1部分中的算法来使用此分段树回答查询。

答案 1 :(得分:1)

声明:

输入:list<x',x'',Y>

查询输入:(X',X'')

输出:Ymin

约束:

1 ≤ Q, S, m ≤ 10^5
1 ≤ N ≤ 10^9

Time: 1s
Memory: 256 Mb

<强>答案:

您可以使用的数据结构方法:

<强> 1。蛮力:直接遍历列表并执行检查。

<强> 2。排序:对Y [从最低到最高]的列表进行排序,然后迭代它。

注意:排序大型列表非常耗时。

Sort on Y
Ymin = -1                                            //Maintain Ymin
for i[0 : len(input)] :                              //Iterate through tuples
    if Ymin != -1 && Y(i-1) != Yi : return Ymin      // end case
    else if x' > X'' : Ymin = Yi                     //its on right of query tuple
    else if x'<X' && (x' + length <= X') : Ymin = Yi //on left of query tuple
    else next

第3。 Hashmap Map<Y, list< tuple<x',length> > >用于存储每个Y的行列表,并迭代它们以获得最少Y

注意:会花费更多时间进行地图构建。

Iterate through list and build a Map 
Iterate through Map keys :
    Iterate through list of tuples, for each tuple :
        if x' > X'': Continue                            //its on right of query tuple
        else if x'<X' && (x' + length <= X') :  return Y //on left of query tuple
            else next Y

<强> 4。矩阵:您可以构建矩阵,其中1表示占用点,0表示空白。

注意:将花费额外的时间进行Matrix构建,并且通过矩阵进行迭代非常耗时,因此无用。

示例:

    0 1 1 1 0 0 
    1 1 0 1 0 0
    0 1 1 1 1 0