线段树SegmentTree

线段树当中的几个重要操作

1.PushUp

上推操作:由子节点算父节点的信息

p u s h u p push up pushup 操作的目的是为了维护父子节点之间的逻辑关系。当我们递归建树时,对于每一个节点我们都需要遍历一遍,并且电脑中的递归实际意义是先向底层递归,然后从底层向上回溯,所以开始递归之后必然是先去整合子节点的信息,再向它们的祖先回溯整合之后的信息。
我们在这儿就能看出来,实际上push_up是在合并两个子节点的信息,所以需要信息满足结合律!



2.PushDown

下沉操作,又称为懒标记延迟标记:由父节点计算子节点的信息

之所以称为懒标记,是因为当我们在修改一个区间的信息的时候,我们不会把这个区间和它的所有子区间全都修改,而是在根节点的区间上标记一下(这就需要一个额外的信息 a d d add add 来储存我们的修改信息),在用到该区间的时候才进行修改。即延迟修改。

例如我们要修改区间 [ 1 , 10 ] [1, 10] [1,10],我们无须把它的子区间 [ 1 , 5 ] [1, 5] [1,5] [ 6 , 10 ] [6, 10] [6,10] 以及 [ 1 , 5 ] [1, 5] [1,5] [ 6 , 10 ] [6, 10] [6,10] 的子区间全部递归修改一番直到修改到叶子节点然后逐层回溯,这样操作的时间复杂度是可以高达 O ( N l o g N ) O(NlogN) O(NlogN) 的。
我们可以直接在区间 [ 1 , 10 ] [1, 10] [1,10] 标记一下,表示我们修改了这个区间了,但是我们不对他的子区间进行操作,直到某一次查询或者修改需要使用这个区间的时候,我们才修改这个区间并把它的修改下沉到子区间。

不过我的习惯是,当我们需要标记一个区间的时候,直接就把此区间修改了。

总而言之,懒标记的作用是记录每次、每个节点要更新的值,也就是delta,但线段树的优点不在于全记录(全记录依然很慢qwq),而在于传递式记录:

整个区间都被操作,记录在公共祖先节点上;只修改了一部分,那么就记录在这部分的公共祖先上;



3.Build

将一段区间初始化为线段树



4.Modify

  1. 单点( P u s h U p PushUp PushUp
  2. 区间( P u s h D o w n PushDown PushDown + P u s h u p Pushup Pushup



5.Query

时间复杂度: O ( 4 × l o g N ) O(4 \times logN) O(4×logN)
查询某一段区间的信息



6.与树状数组的比较

线段树的常数比树状数组
线段树的 l o g n logn logn 4 4 4 倍的 l o g n logn logn
树状数组的 l o g n logn logn 1 1 1 倍的 l o g n logn logn
线段树点修改和区间查询的时间复杂度为



7. u p up up d o w n down down操作的使用时机

主要是从定义出发

(1) p u s h u p pushup pushup

p u s h u p pushup pushup 的定义是通过合并子节点的信息并上传修改根节点的信息,只要修改子节点的信息,就要在回溯的过程中修改父节点的信息。

因此, p u s h u p pushup pushup 一般是在代码的末尾出现,只有子节点都修改完成之后,才可以吧子节点的信息合并推到父节点上。

例如:

(1)建树的过程中,如果区间可以继续划分,那么我们就要递归该根节点的左右区间,当递归左右区间结束的时候,就要 p u s h u p pushup pushup 合并返回子节点的信息。
(2)修改区间信息,如果我们修改的区间不能在当前区间直接完成修改,而是要在它的左右区间分别修改一部分,例如区间 [ 1 , 10 ] [1, 10] [1,10],我们要修改 [ 4 , 7 ] [4, 7] [4,7] ,就需要分别修改它的左子树区间 [ 1 , 5 ] [1, 5] [1,5] 和右子树区间 [ 6 , 10 ] [6, 10] [6,10]。并在修改结束的时候 p u s h u p pushup pushup 合并子节点的修改信息返回到父节点。

(2) p u s h d o w n pushdown pushdown

p u s h d o w n pushdown pushdown的定义是下沉父节点的修改信息到子节点,只要父节点的信息被修改,就要下沉父节点的修改信息到子节点上。

因此, p u s h d o w n pushdown pushdown 一般在代码的头出现,否则此时子节点的信息未被修改,或者说出现修改重叠的情况。

并且,使用 p u s h d o w n pushdown pushdown 的时候一般都是在区间分裂的时候使用的。即,我们不能在当前区间直接完成操作,需要分别在它的左区间或者右区间或者两个子区间进行操作。而由于我们使用了懒标记,只修改了根区间的信息,它的子区间还未修改,所以说我们要把它的修改信息下沉到子区间并修改和标记子区间。

例如:

(1)执行查询操作,此时我们得到区间的一些信息,当然要把还未执行的操作执行一下。
(2)执行修改操作,这个不太好理解,虽然说我们的修改操作也可能会使用到两个子区间的信息,但我们只是对区间加上一个懒标记,为什么还要把根区间的懒标记下沉呢?这是因为我们上面的 pushup 会出现在修改操作里,如果懒标记没有下传就会导致子节点的值没有第一时间更新,父节点就会被错误的更新。

再举个例子解释一下第(2)点:

  1. 初始化区间 [ 1 , 10 ] [1, 10] [1,10] 所有元素全为 1 1 1,建树,维护两个信息: l a z y T a g lazyTag lazyTag 和 区间和 s u m sum sum
  2. 执行修改操作 [ 1 , 10 ] [1, 10] [1,10] 的每个元素都加上 2 2 2,此时区间元素全为3。我们的懒标记修改了区间 [ 1 , 10 ] [1, 10] [1,10] s u m sum sum s u m [ 1 , 10 ] = 30 sum[1, 10] = 30 sum[1,10]=30,但此时区间 [ 1 , 5 ] , [ 6 , 10 ] , . . . , [ 9 , 9 ] , [ 10 , 10 ] [1, 5], [6, 10], ... ,[9, 9],[10, 10] [1,5],[6,10],...,[9,9],[10,10]的值依然是初始状态下的值。 最后 p u s h u p pushup pushup (由于 [ 1 , 10 ] [1, 10] [1,10] 为整个树的根节点,所以此时 p u s h u p pushup pushup 啥都没做)。
  3. 再次执行修改操纵 [ 1 , 5 ] [1, 5] [1,5] 的每个元素都加上 1 1 1(不执行 p u s h d o w n pushdown pushdown),紧接着由于 [ 1 , 5 ] [1, 5] [1,5] 无法包含当前区间 [ 1 , 10 ] [1, 10] [1,10] ,分裂区间为 [ 1 , 5 ] , [ 6 , 10 ] [1, 5], [6, 10] [1,5],[6,10], 递归到左区间 [ 1 , 5 ] [1, 5] [1,5],此时正好包含该区间,修改区间 [ 1 , 5 ] [1, 5] [1,5] 的值为 10 10 10,然后 p u s h u p pushup pushup 该区间的修改信息到父区间 [ 1 , 10 ] [1, 10] [1,10], s u m [ 1 , 10 ] = s u m [ 1 , 5 ] + s u m [ 6 , 10 ] = 10 + 5 = 15 sum[1, 10] = sum[1, 5] + sum[6, 10] = 10 + 5 = 15 sum[1,10]=sum[1,5]+sum[6,10]=10+5=15,然后回溯到父区间 [ 1 , 10 ] [1, 10] [1,10],执行 p u s h u p pushup pushup(由于是树根不执行),结束。
  4. 最后我们发现第二次操作 s u m [ 1 , 10 ] = 15 sum[1, 10] = 15 sum[1,10]=15,甚至比第一次操作的 s u m sum sum 更小了,究其原因在于第一次操作给区间 [ 1 , 10 ] [1, 10] [1,10] 打上的懒标记没有在第二次操作下沉到子区间,导致子区间实际上没有执行第一次修改操作。
  5. 如果我们在分裂区间之前执行 p u s h d o w n pushdown pushdown,那么此时有 s u m [ 1 , 5 ] = 15 , s u m [ 6 , 10 ] = 15 sum[1, 5] = 15, sum[6, 10] = 15 sum[1,5]=15,sum[6,10]=15,然后执行第二次修改操作 s u m [ 1 , 5 ] = 15 + 5 = 20 sum[1, 5] = 15 + 5 = 20 sum[1,5]=15+5=20,最后合并区间 [ 1 , 5 ] , [ 6 , 10 ] [1, 5], [6, 10] [1,5],[6,10] 的和上传到区间 [ 1 , 10 ] [1, 10] [1,10],此时 s u m [ 1 , 10 ] = 20 + 15 = 35 sum[1, 10] = 20 + 15 = 35 sum[1,10]=20+15=35 就正确了



8.常见的SE错误来源

  1. 数组空间没有开四倍
  2. m i d = l + r > > 1 mid = l + r >> 1 mid=l+r>>1 还是 m i d = t r [ u ] . l + t r [ u ] . r > > 1 mid = tr[u].l + tr[u].r >> 1 mid=tr[u].l+tr[u].r>>1
  3. u < < 1 u << 1 u<<1 或者 u < < 1 ∣ 1 u << 1|1 u<<1∣1 是否写错
  4. b u i l d build build 里面 e l s e else else 循环中,是否初始化 t r [ u ] = { l , r . . . } tr[u] =\{l, r... \} tr[u]={l,r...}



例题

1.区间加法

模板题

步骤二:思路
步骤三:代码


2.区间乘法 + 区间加法

步骤一:题目描述

模板题

步骤二:思路
步骤三:代码


3.区间最大公约数

步骤一:题目描述

结论

步骤二:思路
步骤三:代码


4.最大连续字段和

步骤一:题目描述

维护额外信息

步骤二:思路
步骤三:代码


4.区间最值

步骤一:题目描述

思维

步骤二:思路
步骤三:代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/73529.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SSH免密登录服务器方法

Window免密连接Linux系统 生成公匙 ssh-keygen -t rsa一路回车生成公钥 复制公匙&#xff0c;使用记事本打开复制全部内容 notepad C:\Users\DELL\.ssh\id_rsa.pub内容如"ssh-rsa AAAAB3NzaC1yc2EAAAA…" 远程登录服务器将内容写入~/.ssh/authorized_keys echo …

Go 1.24 新特性解析:泛型类型别名、弱指针与终结器改进

文章精选推荐 1 JetBrains Ai assistant 编程工具让你的工作效率翻倍 2 Extra Icons&#xff1a;JetBrains IDE的图标增强神器 3 IDEA插件推荐-SequenceDiagram&#xff0c;自动生成时序图 4 BashSupport Pro 这个ides插件主要是用来干嘛的 &#xff1f; 5 IDEA必装的插件&…

MySQL 表 t1 建立联合索引 (a, b, c),在 where a < ? and b > ? and c < ? 中哪些索引生效

文章目录 联合索引 abc 均范围扫描时的索引生效情况无回表 表数据量非常少无回表 表数据量多有回表总结 联合索引 abc 均范围扫描时的索引生效情况 场景&#xff1a;表 t1 建立联合索引 (a, b, c)&#xff0c;在 where a < ? and b > ? and c < ? 中哪些索引生效…

海外营收占比近4成,泡泡玛特全球化战略迎收获期

3月26日&#xff0c;泡泡玛特国际集团发布2024全年财报。财报显示&#xff0c;2024年泡泡玛特实现营收130.4亿元&#xff08;人民币&#xff0c;下同&#xff09;&#xff0c;同比增长106.9%&#xff0c;经调整净利润34.0亿元&#xff0c;同比增长185.9%。中国内地营收79.7亿元…

ctf-web: 不统一的解析 + sql注入要求输入与输出相等 -- tpctf supersqli

# 从 django.shortcuts 模块导入 render 函数&#xff0c;用于渲染模板 from django.shortcuts import render # 从 django.db 模块导入 connection 对象&#xff0c;用于数据库连接 from django.db import connection# 此模块用于创建视图函数 # 从 django.http 模块导入 Http…

LLM推理加速框架有哪些

LLM推理加速框架有哪些 目录 LLM推理加速框架有哪些1. TensorRT简介简单使用示例2. Triton Inference Server简介简单使用示例3. SGLang简介简单使用示例4. vLLM简介简单使用示例1. TensorRT 简介 TensorRT 是 NVIDIA 推出的一个用于高性能深度学习推理的 SDK。它能够对训练好…

【深度学习与实战】2.1、线性回归模型与梯度下降法先导案例--最小二乘法(向量形式求解)

为了求解损失函数 对 的导数&#xff0c;并利用最小二乘法向量形式求解 的值&#xff0c;我们按照以下步骤进行&#xff1a; ‌1. 损失函数的含义‌ 这是‌线性回归‌的平方误差损失函数&#xff0c;目标是最小化预测值 与真实值 之间的差距。 ‌定义损失函数‌&#xf…

S7-1200对V90 PN进行位置控制的三种方法

S7-1200系列PLC通过PROFINET与V90 PN伺服驱动器搭配进行位置控制,实现的方法主要有以下三种: ? 方法一、在PLC中组态位置轴工艺对象,V90使用标准报文3,通过MC_Power、MC_MoveAbsolute等PLC Open标准程序块进行控制, 这种控制方式属于中央控制方式(位置控制在PLC中计算,驱…

爱普生FC-135晶振5G手机的极端温度性能守护者

在5G时代&#xff0c;智能手机不仅需要高速率与低延迟&#xff0c;更需在严寒、酷暑、振动等复杂环境中保持稳定运行。作为 5G 手机的核心时钟源&#xff0c;爱普生32.768kHz晶振FC-135凭借其宽温适应性、高精度稳定性与微型化设计&#xff0c;成为5G手机核心时钟源的理想选择&…

ROS--IMU数据包

IMU惯性测量单元 一&#xff1a;IMU二&#xff1a;ROS中三&#xff1a;IMU数据包三&#xff1a;总结 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一&#xff1a;IMU IMU&#xff08;Inertial Measurement Unit&#xff0c;惯性测量单元&#xff09…

数据文件误删除,OceanBase中如何重建受影响的节点

当不慎误删数据文件且当前没有现成的可替换节点时&#xff0c;在OceanBase中&#xff0c;不必急于采取极端措施&#xff0c;可以考虑运用 server_permanent_offline_time 参数&#xff0c;来重建受影响的节点。 原理&#xff1a; server_permanent_offline_time 是 OceanBase数…

Python:匹配多个字符,如何匹配开头

匹配字符0次或无数次(*)&#xff1a; import re resre.match([A-Z][a-z]*,Lihailu) print(res.group())#提取数据 输出结果可以全部输出 匹配字符至少一次()&#xff1a; import re resre.match([A-Za-z]python,apython) print(res.group())#提取数据(后边只写python会…

Unity-RectTransform设置UI width

不知道有没人需要这样的代码&#xff0c;就是.sizeDelta //不确定是不是英文翻译的原因&#xff0c;基本很难理解&#xff0c;sizeDeltaSize&#xff0c;//未必完全正确&#xff0c;但这么写好像总没错过 //image 在一个UnityEngine.UI.Image 的数组内foreach (var image in l…

java学习——函数式编程(1)

函数式编程 Java 的函数式编程是一种以函数为核心构建逻辑的编程范式,强调不可变性、声明式代码和无副作用的操作。它通过Lambda表达式、函数式接口(如Function、Predicate、Consumer等)和Stream API等特性实现,将计算过程抽象为函数的组合与转换,而非传统的命令式步骤。…

AP CSA FRQ Q2 Past Paper 五年真题汇总 2023-2019

Author(wechat): bigshuang2020 ap csa tutor, providing 1-on-1 tutoring. 国际教育计算机老师, 擅长答疑讲解&#xff0c;带学生实践学习。 热爱创作&#xff0c;作品&#xff1a;ap csa原创双语教案&#xff0c;真题梳理汇总&#xff0c; AP CSA FRQ专题冲刺, AP CSA MCQ小题…

线程池详解:在SpringBoot中的最佳实践

线程池详解&#xff1a;在SpringBoot中的最佳实践 引言 在Java并发编程中&#xff0c;线程池是一种非常重要的资源管理工具&#xff0c;它允许我们在应用程序中有效地管理和重用线程&#xff0c;从而提高性能并降低资源消耗。特别是在SpringBoot等企业级应用中&#xff0c;正…

2025年IT行业技术革命全景解析:从AI到量子计算的落地实践

简介 2025年&#xff0c;全球IT行业正经历一场由AI、量子计算、物联网等技术驱动的变革。从BOE的AI制造系统到德易科技的无人机光伏巡检&#xff0c;从鲲鹏处理器的国产化突破到量子计算的算力革命&#xff0c;技术创新正在重塑产业格局。本文结合最新行业动态与实战案例&…

JVM - 年轻代和老年代

通过一些问题来讨论 JVM 中年轻代和老年代的内容 为什么要区分年轻代和老年代&#xff1f;哪些对像会进入老年代&#xff1f;什么时候会进行年轻代GC&#xff1f;什么时候会进行老年代GC&#xff1f; 1. 为什么要区分年轻代和老年代&#xff1f; 年轻代中的对象大部分都是短期…

【react】在react中async/await一般用来实现什么功能

目录 基本概念 工作原理 优点 注意事项 底层原理 实际应用场景 1. 数据获取 (API 请求) 2. 表单提交 3. 异步状态管理 4. 异步路由切换 5. 异步数据预加载 6. 第三方 API 调用 7. 文件上传/下载 8. 路由导航拦截 关键注意事项 基本概念 async 函数&#xff1a;用…

高维小样本数据的在线流特征选择

发布于24年国际学习和控制论杂志 文献地址 简要总结 《Online streaming feature selection for high-dimensional small-sample data》研究了高维小样本数据&#xff08;HDSS&#xff09;在类别不平衡情况下的在线流式特征选择问题&#xff0c;提出了一种名为OSFSHS的算法。…