1、B站视频链接:C02【模板】线段树+懒标记 Luogu P3372 线段树 1_哔哩哔哩_bilibili
题目链接:P3372 【模板】线段树 1 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
cpp
void build(int p,int l,int r){
tr[p]={l,r,w[l],0};
if(l==r)return;//叶子节点返回
int m=l+r>>1;//不是则裂开
build(lc,l,m);
build(rc,m+1,r);
pushup(p);
}
cpp
void upadate(int p,int x,int y,int k){
if(x<=tr[p].l&&tr[p].r<=y){//覆盖则修改
tr[p].sum+=(tr[p].r-tr[p].l)*k;
tr[p].add+=k;//记上帐
return;
}
int m=tr[p].l+tr[p].r>>1;//不覆盖则裂开
pushdown(p);
if(x<=m)update(lc,x,y,k);
if(y>m)update(rc,x,y,k);
pushup(p);
}
cpp
#define lc p<<1
#define rc p<<1|1
#define N 100005
int n,w[N];
struct node{
int l,r,sum,add;//add是懒标记
}tr[N*4];
void pushup(int p){//向上更新 儿子到父亲
tr[p].sum=tr[lc].sum+tr[rc].sum;
}
void pushdown(int p){//向下更新,父亲还账账
if(tr[p].add){//父亲有欠账
tr[lc].sum=tr[p].add*(tr[lc].r-tr[lc].l+1),//还给左
tr[rc].sum=tr[p].add*(tr[rc].r-tr[rc].l+1),//还给右儿子
tr[lc].add+=tr[p].add;
tr[rc].add+=tr[p].add;
tr[p].add=0;//帐还完了
}
}
void build(int p,int l,int r){
tr[p]={l,r,w[l],0};
if(l==r)return;//叶子节点返回
int m=l+r>>1;//不是则裂开
build(lc,l,m);
build(rc,m+1,r);
pushup(p);
}
void upadate(int p,int x,int y,int k){
if(x<=tr[p].l&&tr[p].r<=y){//覆盖则修改
tr[p].sum+=(tr[p].r-tr[p].l)*k;
tr[p].add+=k;//记上帐
return;
}
int m=tr[p].l+tr[p].r>>1;//不覆盖则裂开
pushdown(p);
if(x<=m)update(lc,x,y,k);
if(y>m)update(rc,x,y,k);
pushup(p);
}
int query(int p,int x,int y){
if(x<=tr[p].l&&tr[p].r<=y)return tr[p].sum;//覆盖则返回
int m=tr[p].l+tr[p].r>>1;//裂开
pushdown(p);
int sum=0;
if(x<=m)sum+=query(lc,x,y);
if(y>m)sum+=query(rc,x,y);
return sum;
}