区间修改线段树

版权声明:转载记得标明出处哦~ https://blog.csdn.net/weixin_43890047/article/details/88775051

区间修改线段树:

函数:

1、up向上传递
2、down父节点向下传递
3、modify区间修改(同时添加lazy标记)
4、query(与单点修改的差别是确认区间后要向下传递lazy标记)

代码:
///这个是区间求和的区间修改线段树
#include<bits/stdc++.h>
using namespace std;
const int MAX_N = 10010;
int s[4*MAX_N] = {0};///维护区间的线段树
int col[4*MAX_N] ={0};  ///向下传值的lazy标记

void up(int p)
{
    s[p] = s[2*p]+s[2*p+1];
}
///down向下传递函数也跟程序实现目的十分相关,改动也十分大
///但一般都有三个参数,编号p,衡量工具l与r
void down(int p,int l,int r)
{
    if(col[p]){      ///说明父节点存在lazy标记,则现向下传递
        int mid = (l+r)/2;
        s[2*p]+=(mid-l+1)*col[p];
        s[2*p+1]+=(r-mid)*col[p];
        col[2*p] += col[p];///传递给子节点lazy标记
        col[2*p+1] +=col[p];
        col[p] = 0; ///去除父节点lazy标记
    }
}
///注意其跟单点操作的差别
void modify(int p,int l,int r,int x,int y,int v)
{
    if(x<=l&&r<=y){
        s[p] += (r-l+1)*v;  ///修改对应区间的值
        col[p] +=v; ///添加lazy标记
        return ;
    }
    down(p,l,r);   ///传本节点的lazy标记,在确认区间后就写上
    int mid = (l+r)/2;
    if(x<=mid){
        modify(2*p,l,mid,x,y,v);
    }
    if(y>mid){
        modify(2*p+1,mid+1,r,x,y,v);
    }
    up(p);          ///不要漏了
}
///区间查询的时候记得也要传递lazy标记(up)

※维护区间最大(小)值的线段树跟单点修改线段树(公告板那题)那篇博客思想很类似,便不作多记录。

其相关的题目:

1、 习题:帕吉的肉钩
2、 习题:区间整数操作
题目较简单,便不做题解了。

习题:黑白石头放在下篇博客来详细记录

猜你喜欢

转载自blog.csdn.net/weixin_43890047/article/details/88775051