【数据结构学习笔记】18:线段树(单点修改)

news2025/7/16 7:13:14

1 线段树上的操作

  • push_up(int u):由子节点的信息去计算父节点的信息,例如两个子节点的区间和,加起来就是父节点表示的区间和。其中u是当前节点编号,表示用u的左右两个子节点来算一下自己这个节点的信息。
  • push_down:将父节点的信息下传到子节点,例如将整个区间加上同一个数,那么将这个操作递归地下传给子节点。push_down也叫做懒标记或者延迟标记。
  • build(int u, int L, int R):将一段区间初始化成线段树。其中u是当前节点编号,L是区间左端点, R是区间右端点。
  • modify:修改操作,可以分为修改单点(比较简单)和修改一个区间(比较复杂,往往需要应用push_down来延迟更新)。
  • query(int u, int L, int R):查询操作,查询某一段区间的信息。其中u是当前节点编号,L是查询区间左端点, R是查询区间右端点。

2 一个例子

线段树除了最后一层之外,形态上是一个满二叉树。比如要维护[1, 10]这个区间,那么根节点就表示[1, 10]。取mid = (L + R) / 2下取整,那么左子节点表达的区间是[L, mid],右子节点表达的区间是[mid + 1, R]。所以维护[1, 10]的线段树就是:
在这里插入图片描述
之前学习的堆也是这样除了最后一层之外就是一个满二叉树的形态, 所以我们存储线段树的方式和堆也是类似的,用一个一维数组来存整棵树。所以对于编号是x的节点,父节点是x / 2下取整(即x >> 2),左儿子的编号是2x(即x << 1),右儿子是2x + 1(即x << 1 | 1)。

3 线段树的空间效率

假设区间里一共有n个最小粒度的区间,估计一下线段树上最坏情况下有多少个节点。
首先叶子节点也就是最小粒度的区间,一定是有n个叶子节点。
那么倒数第二层最坏情况下不会超过叶子节点的个数,也就认为倒数第二层最多n个节点。
那么去掉倒数第一层以外的部分是满二叉树,满二叉树的部分最多就是2n - 1个节点(通过刚刚估计的倒数第二层的最坏情况来计算的)。
那么最后一层最坏情况下是倒数第二层的两倍,也就是最后一层最坏情况下2n个节点。
所以整棵树最坏情况下不会超过(2n - 1) + 2n = 4n - 1个节点,所以开线段树的时候直接开4n个节点这么多的空间。

4 build操作

将区间[L, R]构建到线段树里,节点编号为u,伪代码:

build(int u , int L , int R)
{
	// 记录一下区间左右端点
	tr[u].L = L
	tr[u.R = R
	// 如果是叶子节点就build完成了
	if (L == R) return // 叶子节点因为没有孩子,所以是不用push up的
	// 计算一下中点,递归build左右两边
	int mid = L + R >> 1
	build(u << 1, L, mid)
	build(u << 1 | 1, mid + 1, R)
	// 一般是在这里,也就是子树都build完的时候,函数退栈之前push up一下,用两个子节点反向计算当前节点信息
	push_up(u)
}

5 query操作

假设线段树的每个节点维护的是区间的最大值,在[1, 10]的线段树里要查询[5, 9]这个区间,那么会从根节点开始递归地查询。具体地,要查询的区间[L, R] = [5, 9],当前(在根节点)线段树上节点表示的区间是[TL, TR] = [1, 10]。那么[L, R][TL, TR]之间的包含关系决定了query的下一步动作:

  1. 待查询的[L, R]完全包含了当前节点的[TL, TR],这时直接返回[TL, TR]的结果。
  2. 待查询的[L, R]和当前节点的[TL, TR]有交集,那么对左右子节点,有交集的就(分别)递归处理。
  3. 待查询的[L, R]和当前节点的[TL, TR]没有交集,这种情况是不存在的,只要我们保证有交集的时候才会递归调用对这棵子树的处理就能保障这件事了。

在这个例子中,标上黄色圈圈的部分是被递归query到的节点区间。
在这里插入图片描述
这个例子里因为要查的区间比较小所以比暴力做法要查的区间还多了(暴力是查5个,线段树要查8个),但是可以证明线段树的查询效率是log(n)的常数倍,这段证明先略过不看了。

6 单点modify操作

单点modify最终一定会改到某一个叶子节点上去,所以从上到下只要每次往一个子树里去递归调用modify,直到叶子节点的时候把叶子节点的信息改掉,然后在递归退栈的时候沿着调用链对所有非叶子节点push_up重新计算一下即可。

7 push_up操作

tr[u << 1]tr[u << 1 | 1]的信息更新计算tr[u]的信息。

8 例题

8.1 AcWing 1275 最大数

这题只带query和单点modify操作,而且线段树节点除了存查询信息,不需要额外信息。

8.2 AcWing 245 你能回答这些问题吗

这题也是只带query和单点modify操作,但是线段树节点除了存查询信息,还需要额外信息。这个区间信息是最大后缀和和最大前缀和,用来计算父节点横跨两个区间时候的最大子段和。
在这里插入图片描述
横跨两个区间的最大字段和=左子区间最大后缀和+右子区间的最大前缀和。

但是新加入的这两个额外信息也需要能从两个子节点的信息算出来,为了处理盖掉一个子区间的最大前缀或者最大后缀和,还需要存一个区间总和的信息:
在这里插入图片描述
再考虑这个区间总和的信息,一定能从子节点的总和信息算出来,这样就形成闭环了(用y总的话说是完备的)。

8.3 AcWing 246 区间最大公约数

这题除了query操作之外,还带有区间modify操作,但是不需要懒标记push_down的原因是因为我们可以将这个区间modify操作转换成线段树上的单点modify操作。

具体地,考虑到这题的两个操作是:

  1. 区间 [ L , R ] [L, R] [L,R]增加一个数
  2. 查询区间的最大公约数

考虑到区间 [ L , R ] [L, R] [L,R]增加一个数可以转换成对差分数组的 L L L位置增加一个数,再对 R + 1 R+1 R+1位置减去这个数,可以试着考虑能不能用差分数组扔到线段树里去维护。

因为 a 1 , a 2 , . . . , a n a_1, a_2, ..., a_n a1,a2,...,an的最大公约数就等于 a 1 , a 2 − a 1 , . . . , a n − a n − 1 a_1, a_2 - a_1, ..., a_n - a_{n-1} a1,a2a1,...,anan1的最大公约数,所以如果记
b i = a i − a i − 1 b_i = a_i - a_{i-1} bi=aiai1

那么对 a a a数组求区间[L, R]的最大公约数,等同于先求
b L + 1 , . . . b R b_{L+1}, ... b_R bL+1,...bR

的最大公约数,再和 a L a_L aL求一下最大公约数即可。那么前者就是差分数组的最大公约数了,直接扔到线段树里维护,线段树结点只放最大公约数这个信息的话,对最大公约数的计算就已经是完备的了,因为可以从两个子节点的最大公约数求一下最大公约数得到父区间的最大公约数。然后在对整个区间增加一个数的时候,其实就是做了两次单点modify

另外就是怎么求 a L a_L aL的问题,它相当于是我们维护的差分数组到 L L L为止的前缀和,因为前缀和也是一个区间和,所以我们直接在线段树里再顺便维护一个区间和的信息就可以了,区间和信息之于自己也是完备的。这样每次查询 [ L , R ] [L, R] [L,R]的最大公约数的时候,就是在我们维护的整个差分数列的线段树上先query一下 [ L + 1 , R ] [L + 1, R] [L+1,R]的最大公约数,然后query一下 [ 1 , L ] [1, L] [1,L]的区间和,再把两个值求一个最大公约数即可。

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

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

相关文章

流氓设备检测和预防

自带设备 &#xff08;BYOD&#xff09; 策略中涉及的设备以及这些设备连接到的端口具有多个通信路径。确保这些设备及其路径在进入组织网络时立即被检测、评估和管理至关重要&#xff0c;因为非托管设备很容易成为安全风险。但是&#xff0c;在整个企业网络中同时添加许多设备…

反射、枚举、lambda——小记

文章目录反射反射定义反射相关的类Class 类反射示例获得Class对象的三种方式反射使用 ——代码面试题:你知道有几种创建对象的方式吗?反射优点和缺点枚举Lambda表达式概念Lambda表达式的语法代码反射 反射定义 Java的反射&#xff08;reflection&#xff09;机制是在运行状态…

路由策略和路由控制

路由策略和路由控制 路由策略 针对路由的发布&#xff0c;接收&#xff0c;引入进行控制&#xff0c;从而影响数据的路径或者可达性 路由匹配工具 ACL&#xff1a;访问前缀列表 一个ACL用多条规则组成&#xff0c;不同规则之间通过rule id进行区分&#xff0c;默认rule 步…

(附源码)python办公数据分析系统 毕业设计 021836

Python办公数据分析系统 摘 要 现代办公通过办公自动化系统可以大大提高的效率、节省成本、规范业务和流程&#xff0c;辅助提升管理水平。办公系统在单位信息化中占有非常重要的地位&#xff0c;涉及到单位的各个部门及绝大多数人员&#xff0c;流程和协作方面要求非常强。 办…

[附源码]java毕业设计英语知识竞赛报名系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

NDK 是什么 | FFmpeg 5.0 编译 so 库

前言 NDK 全称 Native Development Kit&#xff0c;也就是原生开发工具包 &#xff0c;官网对它有详细的 中文介绍 。可能一说到 NDK 或 JNI &#xff0c;大家脑子里第一反应就是集成 C/C 。其实 JNI 的含义是 Java Native Interface &#xff0c;这种接口允许 Java 和其他语言…

SpringBoot SpringBoot 原理篇 1 自动配置 1.3 bean 的加载方式【三】

SpringBoot 【黑马程序员SpringBoot2全套视频教程&#xff0c;springboot零基础到项目实战&#xff08;spring boot2完整版&#xff09;】 SpringBoot 原理篇 文章目录SpringBootSpringBoot 原理篇1 自动配置1.3 bean 的加载方式【三】1.3.1 第三种方式1 自动配置 1.3 bean …

体系结构26_输入输出系统(3)

盘阵列&#xff08;RAID&#xff09; 盘阵列容量大、速度快、可靠性高、造价低廉。它是目前解决计算机I/O瓶颈的有效方法之一&#xff0c;有着广阔的发展前景。 盘阵列有多种组织方式&#xff1a; RAID 0 亦称数据分块&#xff08;Striping&#xff09;&#xff0c;即把数据分…

推特群推掀开营销新篇章

与Facebook和Instagram相比&#xff0c;Twitter营销并不是一个非常热门的营销渠道&#xff0c;对于跨境卖家来说可能会有一些陌生和挑战&#xff0c;但是作为一个重要的营销渠道&#xff0c;Twitter在全球市场上拥有超过1.45亿的日活跃用户(超过3.26亿的月活跃用户)&#xff0c…

Pinia基本使用

文章目录1. 介绍2. Pinia 和 Vuex3. 安装和基本使用4. pinia修改数据状态5. pinia持久化处理6. 自定义插件1. 介绍 它是2019 年 11 月对于新版本的vue提供的组合Api进行的尝试&#xff0c;它可以很好的集合vue新的api方法&#xff0c;且还很好的支持ts的写法&#xff0c;Pinia…

web前端-javascript-运算符的优先级(如果遇到的优先级不清楚的,可以使用()来改变优先级)

文章目录运算符的优先级1. , 运算符2. 优先级2.1. 就和数学中一样&#xff0c;在 JS 中运算符也有优先级2.2. 在 JS 中有一个运算符优先级的表2.3. 但是这个表我们并不需要记忆2.3. &&和||的优先级运算符的优先级 var a, b, c;//var a1, b2 , c3; //alert(b);//var re…

sql server如何卸载干净?来看这里

一、如何卸载干净 1.关闭服务 快捷键&#xff1a;windows R&#xff0c;在命令行输入&#xff1a; services.msc&#xff0c;把有关SQL都关闭 &#xff0c;下图所示&#xff1a; 2.到控制面板&#xff0c;卸载 sql server 3.删除磁盘里的文件 我的在c盘里&#xff0c;看各位…

你了解专利的快速预审嘛?

随着经济的发展和科技创新步伐的加快&#xff0c;我国专利申请量的增长速度已大大高于专利审结的速度。专利审查周期的长短不仅影响企业对市场的可预期性&#xff0c;而且影响专利系统对技术创新的产出和扩散的激励作用的发挥。过长的专利审查周期可能会影响企业的竞争预期和获…

[附源码]java毕业设计影院售票系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

为什么选择WordPress作为企业CMS?

WordPress 是世界上最受欢迎的内容管理系统 (CMS)。它为超过40% 的网站和超过 64% 的使用 CMS 的网站提供支持。它易于使用和定制。但它是企业网站的最佳选择吗&#xff1f; 随着大公司意识到它能够构建一个可以根据他们的需求扩展的强大网站的能力&#xff0c;WordPress持续流…

JVM知识体系学习一:JVM基础、java编译后class文件的类结构详解,class分析工具 javap 和 jclasslib 的使用

文章目录前言一、JVM基础1、cross platform 跨平台2、cross language 跨语言3、什么是JVM呢&#xff1f;一张图告诉你4、java从编码到执行*****5. 从跨平台的语言到跨语言的平台6. jvm与class文件格式7. JVM8. javac的过程9. 常见的JVM实现10. JDK JRE JVM二、Class File Forma…

Java多线程(二)——Thread类的相关方法

Thread类的构造方法 Thread() class MyThread extends Thread {Overridepublic void run() {System.out.println("hello Thread");} } public class ThreadDemo {public static void main(String[] args) {Thread t new MyThread();t.start();System.out.println(&…

java数据结构与算法 --- 第十章 数结构基础

第十章 树结构基础 I 引和基本概念 为什么需要树结构? 数组,查询快,增删慢 链表… 而树结构,同时提高查询和增删! 基本概念 术语: 有手就行 II 二叉树 1.概念: 二叉树:每个节点最多有两个子节点的数叫二叉树 满二叉树: 所有叶子节点都在最后一,结点的总数是2^n-1(n是层数…

jeecg-boot中上传图片到华为云obs云存储中

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。 前言 jeecg-boot框架中&#xff0c;其实对接的功能还是挺多的&#xff0c;其中就有文件云存储服务器&#xff0c;不过是阿里云oss的&#xff0c;那如果我们使用的是七牛云&#xff0c;或…

通过TortoiseGit钩子实现提交前检查作者信息是否正确

1、需求背景 从事嵌入式开发的人运行软件依赖于特定的电脑硬件&#xff0c;可能会存在多人在同一台电脑上开发的需求。 我们使用git进行软件代码版本管理&#xff0c;通过提交时的用户名和邮箱区分某次代码是哪个人提交的信息。git自身支持提交的时临时一次设置成其他的用户信…