发布时间:2026/8/20 10:18:00
线段树自我总结 题目链接P3372 【模板】线段树 1 - 洛谷一.定义1.线段树是一棵由线段组成的树分治与二叉树的结合体2.线段树是一种二叉搜索树。什么叫做二叉搜索树首先满足二叉树每个结点度2即每个结点最多有两颗子树。何为搜索我们要知道线段树的每个结点都存储了一个区间也可以理解成一个线段而搜索就是在这些线段上进行搜索操作得到你想要的答案。二.特征1.用分治法自顶向下建立每次分治左右子树各一半。2.每个节点都表示一个“线段”区间非叶子节点包含多个元素叶子节点只包含一个元素。3.除了最后一层其他层都是满的。-----近似完全二叉树可以用数组存树。用一个数组tree[]存储节点。若一个节点的存储下标为k 则其左子节点的下标为2k 其右子节点的下标为2k 1。 4.lr说明这是一个叶子节点。5.lr说明他有两个子节点左儿子[l,m],右儿子[m1,r]其中m(lr)/2;三.作用线段树看起来挺麻烦的他为什么这么高效 每个结点的值代表了以它为根的子树上所有节点的值那么查询这个子树所代表的区间的值时就不必遍历整棵树而是直接读取这棵子树的根值就行了。并且树形结构的操作时间复杂度是O(logn)。 线段树最适合解决的问题的特征是大区间的解可以从小区间的解合并而来。 线段树是算法竞赛中常用的用来维护 区间信息 的数据结构。 线段树可以在 O(log N) 的时间复杂度内实现单点修改、区间修改、区间查询区间求和求区间最大值求区间最小值等操作。四.建树首先我们得先明白几件事情。 每个结点存什么如何存树如何建树1一个结点对应一段区间[l,r]区间内有我们需要的值区间和最值等等所以一个结点内要保存该结点对应区间的左右边界需要的值。2线段树近似完全二叉树可以用数组存树。用一个数组tree[]存储节点。若一个节点的存储下标为o 则其左子节点的下标为2o 其右子节点的下标为2o 1。3建树以n个元素的区间(a[n])为基础建树。以维护区间和为例 tree[]数组大小4*n可能存在空间浪费) 基于递归建树。初始节点为1因为你要从1号节点开始建树。左子树节点是o*2右子树节点是o*21。线段树在构造子树时一个结点的两个子节点是平分这个子树的特征中说过在遍历时左子树范围是[l,m],右子树是 [m1,r],其中m(lr)/2。 线段树建树的时间复杂度为O(n)五.区间修改区间修改操作单点修改区间修改在一开始建树的时候该点是在树中的树中一个点改变可能会引起这棵树的改变。还是以区间求和为例当你改变了一个点这个点的所有父节点都得改变。如图先递归找到要修改的叶子节点直接修改叶子节点上元素的值然后从底往上更新线段树即可但是这样操作时间复杂度最坏是O(n)所以我们还需进行优化六.区间查询区间查询直接递归查询即可。但是在查询过程中要注意懒标记。 完全覆盖和部分覆盖两种情况无懒标记的线段树代码#include bits/stdc.h using namespace std; #define int long long #define endl \n int n, m; const int N 1e5 10; int a[N]; //线段树的结点结构 struct Node { int l, r; int sum; } tree[N 2]; void Build(int i, int le, int ri) // 构建第i号节点对应的区间[le,ri],时间复杂度O(n); {//建立线段树 tree[i].l le; tree[i].r ri; if(leri) {//区间中只有一个数据 叶子节点 tree[i].sum a[le]; return; } //区间中有多个数据 非叶子节点 int mid (le ri) / 2; Build(2 * i, le, mid); Build(2 * i 1, mid 1, ri); tree[i].sum tree[2 * i].sum tree[2 * i 1].sum; } void Update(int i,int le,int ri,int k) {//区间修改-最坏的情况下退化成O(n)--保持logn:懒标记 if(tree[i].ltree[i].r) {//叶子节点的修改 tree[i].sum k; return; } int mid (tree[i].l tree[i].r) / 2; if(lemid)//如果左孩子对应的区间有修改的部分先修改左孩子 { Update(2 * i, le, ri, k); } if(mid1ri)//如果右孩子对应的区间有修改的部分先修改右孩子 { Update(2 * i 1, le, ri, k); } tree[i].sum tree[2 * i].sum tree[2 * i 1].sum; } int query(int i,int le,int ri) {//查询[le,ri] int ans 0; if(tree[i].lletree[i].rri){ //第i个节点对应的区间被查询的区间完全覆盖第i个节点对应的区间和要被算到答案里面 return tree[i].sum; } else {//第i个节点对应的区间没有被查询的区间完全覆盖 int mid (tree[i].l tree[i].r) / 2; if(lemid) { ans query(2 * i, le, ri); } if(rimid1) { ans query(2 * i 1, le, ri); } return ans; } } void solve() { cin n m; for (int i 1; i n;i) { cin a[i]; } Build(1, 1, n); // 从根节点开始建树 根节点1号节点[1,n]; int q, x, y, k; while(m--){ cin q; if(q1) { cin x y k; Update(1, x, y, k); } else { cin x y; int ans query(1, x, y); cout ans endl; } } } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); int T 1; // cin T; while (T--) { solve(); } return 0; }七.懒标记为了降低时间复杂度我们引进一个新玩意lazy-tag懒标记。tag[i]记录了区间i的修改这样就不用一个一个的再去修改去区间的内的每个元素了。也可以直接在结构体中加tag属性。 那啥时候修改一会再修改。 既然不一个个的改那我们就改整体 当我们进行修改时先只对这个线段区间上进行整体上的修改其内部每个元素的值先不修改。只有当查找到的区间[l,r]不包含在给定的区间[L,R]时即lL||rR时才把变化值传给下一层的子区间即修改内部元素。完全覆盖部分覆盖八.down函数down这个函数也就是当需要查询某个结点的子树时需要用到这个函数函数功能就是更新子树的lazy值可以理解为平时先把事情放着等到哪天要检查的时候就临时再去做而且做也不是一次性做完检查哪一部分它就只做这一部分。是不是感受到了什么是Lazy_tag实至名归带有懒标记的线段树#include bits/stdc.h using namespace std; #define int long long #define endl \n int n, m; const int N 1e5 10; int a[N]; //线段树的结点结构 struct Node { int l, r; int sum; int lazy_tag; //lazy_tag0说明该节点对应的区间没有被修改过!0被修改过 } tree[N 2]; void pushup(int i) {//合并左右子节点的信息到父节点 tree[i].sum tree[2 * i].sum tree[2 * i 1].sum; } void Build(int i, int le, int ri) // 构建第i号节点对应的区间[le,ri],时间复杂度O(n); {//建立线段树 tree[i].l le; tree[i].r ri; if(leri) {//区间中只有一个数据 叶子节点 tree[i].sum a[le]; return; } //区间中有多个数据 非叶子节点 int mid (le ri) / 2; Build(2 * i, le, mid); Build(2 * i 1, mid 1, ri); pushup(i); } void apply(int i,int k) {//将懒标记应用到当前节点 tree[i].lazy_tag k; // 有可能连续多次修改 tree[i].sum (tree[i].r - tree[i].l 1) * k; } void pushdown(int i) { if (tree[i].lazy_tag ! 0) { apply(2 * i, tree[i].lazy_tag); apply(2 * i 1, tree[i].lazy_tag); tree[i].lazy_tag 0; } } void Update(int i, int le, int ri, int k) { // 引入懒标记-保持在O(logn); if(tree[i].lletree[i].rri) {//第i个节点对应的区间被要修改的区间完全覆盖 apply(i, k); return; } else { pushdown(i);//下传懒标记把第i个节点的两个孩子对应的区间把之前欠的先修改了 int mid (tree[i].l tree[i].r) / 2; if(lemid) { Update(2 * i, le, ri, k); } if(rimid1) { Update(2 * i 1, le, ri, k); } pushup(i); } } int query(int i, int le, int ri) { // 查询[le,ri] int ans 0; if (tree[i].l le tree[i].r ri) { // 第i个节点对应的区间被查询的区间完全覆盖第i个节点对应的区间和要被算到答案里面 return tree[i].sum; } else { // 第i个节点对应的区间没有被查询的区间完全覆盖 pushdown(i); // 下传懒标记把第i个节点的两个孩子对应的区间把之前欠的先修改了 int mid (tree[i].l tree[i].r) / 2; if (le mid) { ans query(2 * i, le, ri); } if (ri mid 1) { ans query(2 * i 1, le, ri); } return ans; } } void solve() { cin n m; for (int i 1; i n;i) { cin a[i]; } Build(1, 1, n); // 从根节点开始建树 根节点1号节点[1,n]; int q, x, y, k; while(m--){ cin q; if(q1) { cin x y k; Update(1, x, y, k); } else { cin x y; int ans query(1, x, y); cout ans endl; } } } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); int T 1; // cin T; while (T--) { solve(); } return 0; }

相关新闻

2026/8/20 10:12:59

2026大屏轻薄笔记本排行榜:16英寸全能机型选购指南

16英寸大屏轻薄本正在成为办公族与学生群体的主流选择,更大的视野带来更高效的分屏操作与表格处理体验。随着处理器能效与机身工艺的不断突破,大屏与便携已可兼得。在4000元至6000元的主流预算区间,一批兼具素质与轻量化的大屏全能本已走向成…

2026/8/20 10:12:59

2026三款热门云手机盘点,不同需求怎么选?

市面上云手机品类繁多,不同产品侧重点差异很大,有的擅长安卓游戏多开,有的主打原生 iOS 云端环境。今天分享三款热度很高的产品,大家可以对照自己的场景挑选,客观拆解各自长处。一、雷电云手机雷电云继承雷电模拟器多年…

2026/8/20 11:33:20

大气层系统1.7.1整合包实操手册:从SD卡布局到故障自救全流程

大气层系统1.7.1整合包实操手册:从SD卡布局到故障自救全流程 【免费下载链接】Atmosphere-stable 大气层整合包系统稳定版 项目地址: https://gitcode.com/gh_mirrors/at/Atmosphere-stable 大气层系统开机后的加载画面,深蓝渐变背景下程序符号逐层…

2026/8/20 11:33:20

Claude Code 接入 Databricks Claude 模型完整教程(Windows 版)

最近在体验各种 AI Coding 工具时,发现 Claude Code 在代码理解、项目分析、多文件修改等方面表现相当不错。 不过对于很多企业用户来说,直接连接 Anthropic 官方服务并不方便。幸运的是,Databricks 已经提供了 Anthropic Endpoint&#xff…

2026/8/20 11:33:20

PPT放映两侧黑边怎么去掉?三种全屏铺满的设置方法详解

辛苦做好的PPT,到了放映环节却“翻车”了——投影幕或显示器上,幻灯片内容没有铺满全屏,左右两边多出两条碍眼的黑边。这不仅影响视觉效果,也让精心设计的版面大打折扣。很多人以为是电脑或投影仪出了问题,其实这只是P…

2026/8/20 11:33:20

Excel VBA自动化:从明细数据一键生成标准收购单

在实际 Excel 数据处理工作中,我们经常遇到这样的场景:手头有一份包含大量明细数据的表格,需要根据这些明细,快速、准确地汇总并生成一份格式规范的收购单。手动复制粘贴不仅效率低下,而且极易出错。此时,利…

2026/8/20 11:33:20

史海拾贝 —— 历史知识答题小工具PC端

一、项目概述史海拾贝 是一款面向历史爱好者的本地知识问答小工具,以「历史基础知识问答」为核心,支持离线使用、桌面安装,无需联网即可随时随地刷题。项目采用纯前端技术栈(单文件 HTML Service Worker),…

2026/8/20 10:17:13

工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

第四篇:反射——高频能量撞墙之后会发生什么? —— 你以为信号已经过去了,其实它正在回来打你 老Q的现场笔记 第五季,我们正式进入工业神经系统层。这里不再是单个设备的战斗,而是整个工厂“经脉”层面的秩序之战。从这一篇开始,你将第一次看清:看似简单的信号传播,背…

2026/8/19 15:09:57

工业传感器与变送器详解:序章 从物理世界到工业数据

序章 从物理世界到工业数据 ——重新认识工业传感器与变送器 工业自动化系统正变得日益复杂。今天的工业现场早已不是简单的控制回路,而是由多层技术共同构成的立体体系:PLC、DCS、SCADA、MES、工业互联网、边缘计算与人工智能。控制系统可以执行复杂算法,工业网络可以实现…

2026/8/20 0:01:41

Cline、Hermes、OpenClaw 都能连:HTTP 型 MCP 客户端全适配

后台被问得最多的一类问题是:“我用的是 Cline / Hermes / OpenClaw,能连察元的 WPS 文档服务吗?” 统一回答:能。而且这个"都能连"值得单独写一篇——不是我们挨个给每个客户端做了适配,而是所有这些客户端…

2026/8/20 0:01:41

46 个文档工具一次看懂:察元AI文档助手 MCP 工具目录速览

把察元AI文档助手接进 Claude Code 之后,我建议的第一件事不是急着下提示词,而是把它的 MCP 工具目录过一遍——46 个工具(MCP 目录版本 0.10.0),乍看吓人,其实按"一份文档的生命周期"分组之后非…

2026/8/20 8:35:23

实测才敢推 AI论文网站 2026最新测评与推荐

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。一、综…

2026/8/20 9:15:29

2026必备!AI论文网站测评:最新推荐与深度对比

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

2026/8/19 16:39:34

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…