【数据结构学习笔记】18:线段树(建树、单点修改、区间查询)

2023-11-15

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]的区间和,再把两个值求一个最大公约数即可。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【数据结构学习笔记】18:线段树(建树、单点修改、区间查询) 的相关文章

  • 用户数据中的幸存者偏差

    幸存者偏差 Survivorship bias 是一种常见的逻辑谬误 意思是没有考虑到筛选的过程 忽略了被筛选掉的关键信息 只看到经过筛选后而产生的结果 先讲个故事 二战时 无奈德国空防强大 盟军战机损毁严重 于是军方便找来科学家统计飞机受
  • 小白刷题之图形输出

    拓展 string string int num char ch num表示打印字符个数 ch表示打印内容 include
  • 2024年网络安全十10大发展趋势发布

    2023年网络安全十10大发展趋势发布 近日 中国计算机学会 CCF 计算机安全专委会中 来自国家网络安全主管部门 高校 科研院所 大型央企 民营企业的委员投票评选出2023年网络安全十大发展趋势 福利 趋势一 数据安全治理成为数字经济的基
  • 【EI复现】基于深度强化学习的微能源网能量管理与优化策略研究(Python代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 2 1 有 无策略奖励 2 2 训练结果1
  • 2024年华为OD机试真题-小明找位置-Java-OD统一考试(C卷)

    题目描述 小朋友出操 按学号从小到大排成一列 小明来迟了 请你给小明出个主意 让他尽快找到他应该排的位置 算法复杂度要求不高于nLog n 学号为整数类型 队列规模 lt 10000 输入描述 1 第一行 输入已排成队列的小朋友的学号 正整
  • 206.翻转链表

    翻转链表 力扣 LeetCode 官网 全球极客挚爱的技术成长平台 备战技术面试 力扣提供海量技术面试资源 帮助你高效提升编程技能 轻松拿下世界 IT 名企 Dream Offer https leetcode cn problems re
  • 基于卡尔曼的混合预编码技术用于多用户毫米波大规模MIMO系统研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码及文章
  • 华为OD机试2024年最新题库(Python)

    我是一名软件开发培训机构老师 我的学生已经有上百人通过了华为OD机试 学生们每次考完试 会把题目拿出来一起交流分享 重要 2024年1月 5月 考的都是OD统一考试 C卷 题库已经整理好了 命中率95 以上 这个专栏使用 Python解法
  • 利用CHAT写实验结论

    问CHAT 通过观察放置在玻璃表面上的单个水滴 人们可以观察到水滴充当成像系统 探究这样一个透镜的放大倍数和分辨率 CHAT回复 实验报告标题 利用玻璃表面的单一水滴观察成像系统的放大倍数和分辨率 一 实验目的 通过对比和测量 研究和探索玻
  • 矩阵基本操作3

    题目描述 问题描述 定义一个N M N M lt 100 的矩阵 将一个该矩阵的行和列的元素互换 存到另一个二维数组中 输入格式 一行两个整数 N M 中间用空格隔开 表示矩阵有N行 M列 接下来共N行M列表示矩阵 输出格式 输出转置以后的
  • 数据结构——排序

    前言 哈喽小伙伴们好久不见 也是顺利的考完试迎来了寒假 众所周知 不怕同学是学霸 就怕学霸放寒假 假期身为弯道超车的最佳时间 我们定然是不能懒散的度过 今天我们就一起来学习数据结构初阶的终章 七大排序 本文所有的排序演示都为升序排序 目录
  • msyql 异常,别干着急,70%的问题都在这里!

    2024软件测试面试刷题 这个小程序 永久刷题 靠它快速找到工作了 刷题APP的天花板 CSDN博客 文章浏览阅读2 3k次 点赞85次 收藏11次 你知不知道有这么一个软件测试面试的刷题小程序 里面包含了面试常问的软件测试基础题 web自
  • 【计算机毕业设计】OA公文发文管理系统_xtv98

    近年来 人们的生活方式以网络为主题不断进化 OA公文发文管理就是其中的一部分 现在 无论是大型的还是小型的网站 都随处可见 不知不觉中已经成为我们生活中不可或缺的存在 随着社会的发展 除了对系统的需求外 我们还要促进经济发展 提高工作效率
  • 【卡尔曼滤波】具有梯度流的一类系统的扩散映射卡尔曼滤波器研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码 数据 文章
  • 基于卡尔曼的混合预编码技术用于多用户毫米波大规模MIMO系统研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码及文章
  • 独家 | 鸿蒙(HarmonyOS)开发详细学习笔记免费分享

    前言 华为宣布 将在1月18日 在北京 上海 杭州 南京 成都 厦门 武汉 长沙 8 大城市同时召开大会 届时将揭秘鸿蒙生态和 HarmonyOS NEXT 进阶新篇章 简单的来说就是 纯血鸿蒙系统 即将彻底揭晓 鸿蒙系统自推出来以来 就一
  • 计算机Java项目|基于SSM的微课学习系统

    作者主页 编程指南针 作者简介 Java领域优质创作者 CSDN博客专家 CSDN内容合伙人 掘金特邀作者 阿里云博客专家 51CTO特邀作者 多年架构师设计经验 腾讯课堂常驻讲师 主要内容 Java项目 Python项目 前端项目 人工智
  • 「优选算法刷题」:移动零

    嗨 这个假期罗根开始接触了算法 在为今年的蓝桥杯做准备 所以 开个新专栏 记录记录自己做算法题时的心得 一 题目 给定一个数组 nums 编写一个函数将所有 0 移动到数组的末尾 同时保持非零元素的相对顺序 请注意 必须在不复制数组的情况下
  • 【GRNN-RBFNN-ILC算法】【轨迹跟踪】基于神经网络的迭代学习控制用于未知SISO非线性系统的轨迹跟踪(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 2 1 第1部分 2 2 第2部分
  • 高精度运算合集,加减乘除,快速幂,详细代码,OJ链接

    文章目录 零 前言 一 加法 高精度加法步骤 P1601 A B 二 减法 高精度减法步骤

随机推荐

  • lapack c语言,Visual C ++ 2010和Lapack,Blas库(Visual C++ 2010 and Lapack, Blas libraries)

    Visual C 2010和Lapack Blas库 Visual C 2010 and Lapack Blas libraries 我想使用Blas和Lapack库来使用一些rutines 但我不知道如何在Visual C 2010使用它
  • word2016如何插入目录以及页码

    不废话 直接写入步骤 具体步骤如下 插入目录 第一步 切换到视图 在视图页面点击大纲视图 第二步 左上角设置各个标题的级别 如下 分别点击引用 目录 选择一个即可设置好目录 第二步的图片 从第二页插入页码 双击调出页眉页脚 设置页码格式 起
  • 刃边法计算MTF(ESF、LSF、PSF)

    MTF 调制传递函数 评价一个成像系统目前主流的办法主要有三种TV line检测 MTF检测 和SFR检测 MTF是Modulation Transfer Function的英文简称 中文为调制传递函数 是指调制度随空间频率变化的函数称为调
  • 自学网络安全究竟该从何学起?

    一 为什么选择网络安全 这几年随着我国 国家网络空间安全战略 网络安全法 网络安全等级保护2 0 等一系列政策 法规 标准的持续落地 网络安全行业地位 薪资随之水涨船高 未来3 5年 是安全行业的黄金发展期 提前踏入行业 能享受行业发展红利
  • IDEA旗舰版安装与概述

    1 IDEA介绍 IDEA 全称 IntelliJ IDEA 是java编程语言开发的集成环境 IntelliJ在业界被公认为最好的java开发工具 尤其在智能代码助手 代码自动提示 重构 JavaEE支持 各类版本工具 git svn等
  • Cobalt Strike Malleable C2

    郑重声明 本笔记编写目的只用于安全知识提升 并与更多人共享安全知识 切勿使用笔记中的技术进行违法活动 利用笔记中的技术造成的后果与作者本人无关 倡导维护网络安全人人有责 共同维护网络文明和谐 Cobalt Strike Malleable
  • 代码技巧——如何关闭订单?延迟任务的实现方案【建议收藏】

    先思考个问题 为什么要关闭订单 业务上 1 提供待付款时间 而不是简单的 一次付款机会 提高业务指标之一的成单率 成单率 成功下单的人数 发起支付的人数 2 下单成功意味着这个商品被当前订单占用 库存已经预扣减 如果迟迟不支付则需要回收库存
  • ‘WiFi‘ was not declared in this scope报错处理方法

    造成原因 文件头没有定义相应的函数或变量 处理办法 文件头添加以下代码 include
  • java 对称的二叉树

    1 对称的二叉树 1 题目描述 请实现一个函数 用来判断一颗二叉树是不是对称的 注意 如果一个二叉树同此二叉树的镜像是同样的 定义其为对称的 2 解题思路 可以按照类似层次遍历 来判断是否是堆成二叉树 首先根节点以及其左右子树 左子树的左子
  • SpringBoot 防止XSS攻击和SQL攻击拦截器(Filter)

    什么是SQL攻击 什么是XSS攻击 SQL 攻击 把SQL命令插入到Web表单并提交 欺骗服务器执行恶意的SQL命令 XSS 攻击 向有XSS漏洞的网站中输入 传入 恶意的HTML代码 当其它用户浏览该网站时 这段HTML代码会自动执行 从
  • SpringBoot整合ElasticSearch(二)

    文章目录 es的批量操作 es的重中之重 查询 es与springboot集成 es的批量操作 bulk批量操作 导入数据 分析与创建索引 PUT goods mappings properties title type text anal
  • 如何渲染精美3D PCB图

    简介 现在网上大部分PCB渲染方法都比较麻烦 并且会有丝印不清晰 或者走线与铜皮不显现问题 现在分享一种简单有效的PCB渲染方法 图为渲染效果图 工具或材料 AD keyshot 一个带3D封装图的PCB文件 具体步骤 1 AD端操作 在P
  • 写出你所知道的测试工具,并写出他们的用途和优缺点

    写出你所知道的测试工具 并写出他们的用途和优缺点 Jmeter Apache JMeter是Apache组织开发的基于Java的压力测试工具 Apache jmeter 可以用于对静态的和动态的资源 文件 Servlet Perl脚本 ja
  • XXL-JOB详细说明

    XXL JOB 常见任务调度 单机 Timer ExectorService spring scheduled 分布式 xxl job quartz elastic job 原生定时任务的先天缺陷 XXL JOB简介 由调度中心和执行器组成
  • fabric环境

    1 1环境配置链接 https www jianshu com p 6ef2e8425087 https studygolang com articles 17546 Fabric chaincode测试 开发者模式和单元测试 https
  • 计算机网络 传输层的作用,端口,UDP协议,其他传输层协议

    传输层的作用 传输层定义 IP首部中有一个协议字段 用来标识网络层 IP 的 上一层所采用的是哪一种传输层协议 根据这个字段的协议号 就可以识别IP传 输的数据部分究竟是TCP的内容 还是UDP的内容 同样 传输层的TCP和UDP 为了识别
  • 参与 2023 第一季度官方 Flutter 开发者调查

    Flutter 3 7 已经正式发布 每个季度一次的 Flutter 开发者调查也如约而至 邀请社区的各位成员们填写 调查表链接 https flutter cn urls 2023q1wx 本次调研将会涉及既有的对 Flutter 整体和
  • 【李宏毅深度强化学习笔记】—7、Sparse Reward

    原文链接 https blog csdn net ACL lihan article details 104103873 李宏毅深度强化学习笔记 1 策略梯度方法 Policy Gradient 李宏毅深度强化学习笔记 2 Proximal
  • 24个K8S常用场景使用命令(推荐收藏)!

    kubectl是K8S中的一个命令行工具 主要用于管理和操作K8S集群 kubectl通过向K8S API发送REST请求 允许用户与K8S集群中的各种资源进行交互 列如Pod service Deployment等 kubectl提供了一
  • 【数据结构学习笔记】18:线段树(建树、单点修改、区间查询)

    1 线段树上的操作 push up int u 由子节点的信息去计算父节点的信息 例如两个子节点的区间和 加起来就是父节点表示的区间和 其中u是当前节点编号 表示用u的左右两个子节点来算一下自己这个节点的信息 push down 将父节点的