分段树的延迟传播

时间:2015-08-14 17:28:54

标签: algorithm data-structures clrs interval-tree

对于分段树的延迟传播算法,我有些不清楚。根据下面的代码,在查询间隔完全重叠时,更新值只是添加到父节点,并且子节点被标记为延迟更新。但正如您在附图中看到的那样,如果对范围0,1进行了更新+4,那么两棵树的结果完全不同! (左图:没有延迟传播)。

void update_tree(int node, int a, int b, int i, int j, int value) {
if(lazy[node] != 0) { // This node needs to be updated
    tree[node] += lazy[node]; // Update it

    if(a != b) {
        lazy[node*2] += lazy[node]; // Mark child as lazy
            lazy[node*2+1] += lazy[node]; // Mark child as lazy
    }

    lazy[node] = 0; // Reset it
}

if(a > b || a > j || b < i) // Current segment is not within range [i, j]
    return;

if(a >= i && b <= j) { // Segment is fully within range
        tree[node] += value;

    if(a != b) { // Not leaf node
        lazy[node*2] += value;
        lazy[node*2+1] += value;
    }

        return;
}

update_tree(node*2, a, (a+b)/2, i, j, value); // Updating left child
update_tree(1+node*2, 1+(a+b)/2, b, i, j, value); // Updating right child

tree[node] = max(tree[node*2], tree[node*2+1]); // Updating root with max value}

enter image description here

所以问题是,如果在+4更新后调用要求0,1的总和的查询怎么办?

2 个答案:

答案 0 :(得分:1)

首先,您的实施目的似乎是为2个操作提供服务。

  1. 为范围v
  2. 中的所有元素增加值[i, j]
  3. 查询范围max的{​​{1}}值(我从最后一行看到)
  4. 您询问查询范围的总和,这可能与您更新[i, j]的方式无法实现。

    其次,您应该使用tree[node]函数和update函数的延迟传播。

    我将假设您尝试查询范围query的{​​{1}}值。您应该可以获得这样的代码:

    max

答案 1 :(得分:0)

好的,我找到了一种正确的方法来更新段链树,并使用延迟传播来获取该链接中的总和。

Lazy propagation for sums