懒惰传播

时间:2015-01-15 13:36:29

标签: c++ algorithm segment-tree lazy-propagation

我在段树中使用延迟传播解决GSS3 in spoj。我参考了这个博客: Lazy Propagation

如何使用延迟传播继续处理这个问题,我无法理解在这个博客中如何使用懒数组?

#include<iostream>
#include<iomanip>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<vector>
using namespace std;
int tree[(2*MAX)+1],arr[MAX],lazy[(2*MAX)+1];

void build_tree(int node ,int a,int b)
{
    if(a > b) return;
    if(a==b)
    {
        tree[node] = arr[a];
        return;
    }

    build_tree(node*2,a,(a+b)/2);
    build_tree(node*2+1,((a+b)/2)+1,b);
    tree[node] = max(tree[node*2],tree[node*2+1]);

}
void update_tree(int node,int a,int b,int i,int j,int value)
{
    if(lazy[node]!=0)
    {
        tree[node]+=lazy[node];
        if(a!=b)
        {
            lazy[node*2]+= lazy[node];
            lazy[node*2+1]+= lazy[node];
        }
        lazy[node] = 0;
    }
    if(a > b || a > j || b < i)
         return;
    if(a>=i && b<=j)
    {
        tree[node]+=value;
        if(a!=b)
        {
            lazy[node*2]+= value;
            lazy[node*2+1]+= value;
        }
        return;
    }
    update_tree(node*2,a,((a+b)/2),i,j,value);
    update_tree(node*2+1,((a+b)/2)+1,b,i,j,value);
    tree[node] +=(tree[node*2]+tree[node*2+1]);
}
int query_tree(int node,int a,int b,int i,int j)
{
    if(a > b || a > j || b < i) return -inf;
    if(lazy[node]!=0)
    {
        tree[node]+=lazy[node];
        if(a!=b)
        {
            lazy[node*2]+= lazy[node];
            lazy[node*2+1]+= lazy[node];
        }
        lazy[node] = 0;
    }
    if(a>=i && b<=j) return tree[node];
    int q1 = query_tree(node*2,a,((a+b)/2),i,j);
    int q2 = query_tree(node*2+1,((a+b)/2)+1,b,i,j);
    int res = max(q1,q2);
    return res;

}
int main()
{
   int n,m;
   scanf("%d",&n);
   memset(lazy, 0, sizeof lazy);
   for(int i=0;i<n;i++)
      scanf("%d",&arr[i]);
   build_tree(1, 0, n-1);
   scanf("%d",&m);
   for(int i=0;i<m;i++)
   {
       int q;
       scanf("%d",&q);
       if(q==0)
       {
           int x,y;
           scanf("%d",&x);
           scanf("%d",&y);
           update_tree(1,0,n-1,x,y);
        // What Should i do here ?

       }
       if(q==1)
       {
           int x,y;
           scanf("%d",&x);
           scanf("%d",&y);
           query_tree(1,0,n-1,x-1,y-1,);

       }
   }

    return 0;

}

1 个答案:

答案 0 :(得分:1)

lazy数组用于指示节点有挂起的更新,并且必须尽可能地对其进行处理。

设置lazy

当更新递归到达一个完全代表范围的节点时,它不是继续更新子节点,而只是在延迟数组中设置它们的期望值,表明将来某个时候它的子节点也必须更新。然后它从递归返回,避免其子树的其余部分。

何时使用lazy

每当在更新或查询期间访问节点时,递归首先检查是否存在延迟更新挂起并首先应用它(将延迟值传播给节点的子节点)。