注意:这是算法课程的作业中的问题。我不是在寻找解决方案,但可能是我当前方法的一些方向。
以下是问题:
对于区间[0,1],每个点可以着色为白色或黑色。原来, 所有的点都是白色的。
建议支持以下内容的数据结构:
反转(x,y):反转x和y之间每个点的颜色。一个黑点 变成白色,反之亦然。其他点的颜色不受影响。
报告(x):报告x的颜色。
操作应该在O(log(n))时间内工作,其中n是反向数 操作。不要使用超过O(n)的空间。
答案 0 :(得分:2)
区间自平衡搜索树的想法很好。但是,你可以通过有点“懒惰”来节省大量工作。如果需要反转整个子树,只需在子树的根处设置一个标志。稍后,当遍历该节点时,您可以将该标志传播到树中。
另请注意,添加间隔应仅需要最多分割2个现有间隔,因此树最多为O(n)个节点,其中n是执行的反向操作的数量。
举个例子,假设我们有以下树:
现在要求我们撤销(.1,.9)。这会影响树中的每个叶节点,但我们可以访问最多2d个节点,其中d是树的深度。在下图中,我们执行了逆转。边框颜色表明发生了什么:
现在,假设我们被要求报告3.5的颜色。我们遍历树,在我们前进时传播反转旗帜。
如您所见,两个操作都可以在O(d)中完成,其中d是树的深度。如果保持树平衡,则为O(log(n))。
答案 1 :(得分:0)
我使用Segment Tree。您只需要确保将段分成两半,以确保每次更新最多创建O(bits(n))个节点。
您不能证明您使用了O(n)空间,但对于b位输入它是O(b)。如果" y"的位数是常数,然后是O(n)。
只是一个小小的更新示例:
最初,您只有一个节点[0,1]为白色。
[0.0, 1.0, W]
假设您反转[0.25,0.75],您将节点[0,1]拆分为:
-------------[0.0, 1.0, ?]----------
/ \
[0.0, 0.5, ?] [0.5, 1.0, ?]
/ \ / \
[0.0, 0.25, W] [0.25, 0.5, B] [0.5, 0.75, B] [0.75, 1.0, W]