线段树
在线段树的编码中,我们用tag标记被更新的数据节点。当一个节点被打上tag标记,表示它的所有子节点都被更新。
void addtag(ll p,ll l,ll r,ll d)
{
  tag[p]+=d;
  tree[p]+=(r-l+1)*d;
}
但是,在有些情况下,被打上tag标记的节点的子节点需要更新,我们知道,tag标记只修改了被标记的节点,子节点是没用被修改的,所以当我们需要更新子节点时,需要先把tag标记下放到子节点,然后重新更新。
void push_down(ll p,ll l,ll r)
{
  if(tag[p])
  {
    int mid=(l+r)>>1;
    addtag(ls(p),l,mid,tag[p]);
    addtag(rs(p),mid+1,r,tag[p]);
    tag[p]=0;
  }
}
最后,我们的更新函数如下:
void update(ll p,ll L,ll R,ll l,ll r,ll d)
{
  if(L<=l&&r<=R)
  {
    addtag(p,l,r,d);
    return ;
  }
  push_down(p,l,r);    //检查每一个点是否被标记
  ll mid=(l+r)>>1;
  if(L<=mid) update(ls(p),L,R,l,mid,d);
  if(R>mid) update(rs(p),L,R,mid+1,r,d);
  push_up(p);  //向上保持树的数据
}
                    
                
                
            
        
浙公网安备 33010602011771号