如何使用笛卡尔树多次将数组从索引i反转到索引j?

时间:2014-10-11 08:07:52

标签: arrays algorithm data-structures cartesian-tree

假设我有一个给定的数组A.现在有多种形式的操作

reverse i,j // means reverse the array Ai..j inclusive

print i,j

打印数组Ai..j。

示例,

A = 6 9 1 10 4 15 9
reverse 2,3
A = 6 1 9 10 4 15 9
reverse 3,6
A = 6 1 15 4 10 9 9
print 1,4

6 1 15 4

我听说它可以用笛卡尔树来完成。所以我一直在阅读博客here但是我仍然无法理解我们如何使用笛卡尔树来做到这一点,关键和价值应该是什么以及我们应该如何实施?

1 个答案:

答案 0 :(得分:2)

在这个问题中,应该使用带有隐式键的treap(也就是笛卡尔树)(根本没有键,它只是以正确的顺序合并它们)。节点的值是它表示的数组元素。要实现反向操作,您可以为每个节点维护反向标志(如果必须反转则为true,否则为false)并且懒惰地推送(推到这里意味着交换节点的左右子节点并翻转标志的值)它的孩子们。)

推送的伪代码:

void push(Node node)
    if node.flag
        swap(node.left, node.right)
        if node.left != null
            node.left.flag = not node.left.flag
        if node.right != null
            node.right.flag = not node.right.flag