线段树 区间修改

线段树在处理区间修改时,通过使用延迟标记(LAZY)策略可以提高效率。当区间[l,r]完全覆盖节点时,直接返回节点信息作为答案,并在回溯前为节点增加标记。后续需要递归时,检查节点是否有标记,有的话更新子节点并传递标记,保证每个操作的时间复杂度为O(logN)。延迟标记是线段树中一种有效的信息传递方式,也是算法设计的重要思路。" 135280184,594666,华为OD真题:剩余银饰重量算法解析与实现,"['华为OD', '算法', '开发语言']
摘要由CSDN通过智能技术生成

我们对于线段树的区间修改你可以用一个最傻的办法循环进行单点修改(时间复杂度太高十分麻瓜)所以,我们要用一个聪明的做法** 延迟标记**(LAZY)

在限度拿书的“区间查询”指令中,每当遇到被询问区间[l,r]完全覆盖的节点时,可以立即把该节点上存储的信息作为候选答案返回。已经有大佬证明,被询问区间[l,r]在线段树上会被分成O(logN)个小区间(节点)从而在O(logN)的时间内求出答案。

我们在执行修改指令时,同样可以在 L<= Pl <= Pr <= R 的情况下立即返回,只不过在回溯之前向节点P增加一个标记,标识“该节点曾经被修改过,但其子节点尚未被更新”。

如果在后续的指令中,需要从节点P向下递归,我们再检查P是否具有标记。若有标记,就根据标记信息更新P的两个子节点,同时为P的两个子节点增加标记,然后清除P的标记。

也就是说,除了在修改指令中直接划分成的O(logN)个节点之外,对任意给点的修改都延迟到“在后续操作中递归进入他的父亲节点时”再执行。这样一来,每条查询或修改指令的时间复杂度都降低到了O(logN)。这些标记被称为“延迟标记”。延迟标记提供了线段树中从上往下传递信息的方式。这种“延迟”也是设计算法与解决问题的一个重要思路。

附上代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
struct segment_tree{
   
	int l,r;
	long long sum,mark;
}tree[maxn*4];
long long a[maxn];
int n,m;
void pushup(int root){
   
	tree[root].sum = tree[root<<1].sum+tree[root<<1|1].sum;
}
void pushdown(int root){
   
	if(tree[root].mark){
   
		tree[root<<1].sum += tree[root].mark*(tree[root
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值