算法模板-线段树+懒标记

视频连接:C02【模板】线段树+懒标记 Luogu P3372 线段树 1_哔哩哔哩_bilibili 

题目链接:P3372 【模板】线段树 1 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

P3374 【模板】树状数组 1 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

算法思路

递归建树

每个节点存储一段区间的左右端点以及区间的某种属性。通过递归建树。

点修改

点修改可以算是区间修改的一个特例。

区间查询

区间查询:主要的思路是拼凑与拆分。

区间修改

在区间修改当中加入了懒标记以增加效率,它的作用是当找到一个小区间被所求区间覆盖的话,就不再往下进行递归查找,只对当前小区间进行标记。等到下次查询或更新的时候再对小区间中的节点进行更新。

所以懒标记会在对小区间的查询或修改的时候率先更新,这体现在更新区间和查询区间的函数中,在不覆盖的情况下,会率先调用push_down函数对子节点进行更新。

算法模板

#include<bits/stdc++.h>
using namespace std;
#define lc p<<1
#define rc p<<1|1
#define N 100010
typedef long long ll;
ll n,w[N];

struct node{
	ll l,r,sum,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 update(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+1)*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;
}
int main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>w[i];
	build(1,1,n);
	while(m--){
		ll a,b,c,k;
		cin>>a>>b>>c;
		if(a==1){
			cin>>k;
			update(1,b,c,k);
		}else{
			cout<<query(1,b,c)<<endl;
		}
	}
	return 0;
	
} 
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值