版权声明:转载记得标明出处哦~ 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、 习题:区间整数操作
题目较简单,便不做题解了。
而 习题:黑白石头放在下篇博客来详细记录