划分树(Segment Tree)详解:原理、实现与应用
1. 什么是划分树划分树Segment Tree又称线段树是一种用于高效处理区间查询和区间更新的二叉树数据结构。它将一个线性区间通常是数组递归地划分成若干个子区间并将每个子区间的聚合信息如区间和、最大值、最小值等存储在对应的树节点中。划分树的核心思想是分治与预处理通过一次 O(n log n) 的建树操作将原始数据组织成树形结构从而将后续的区间查询和更新操作的时间复杂度降至 O(log n)。2. 划分树的结构与性质2.1 基本结构划分树是一棵完全二叉树通常用数组存储其每个节点代表原始数组的一个连续区间 [l, r]根节点代表整个数组区间 [0, n-1]。内部节点代表其父节点区间的左半部分或右半部分。叶子节点代表长度为 1 的区间即原始数组的单个元素。对于区间 [l, r]其中点 mid (l r) / 2其左右子节点分别代表左子节点区间 [l, mid]右子节点区间 [mid1, r]2.2 存储的信息每个树节点通常存储以下信息区间范围l, r区间的左右端点。聚合值根据具体问题而定例如区间和sum区间最大值max区间最小值min区间乘积product区间 GCD/LCM 等懒标记Lazy Tag用于支持区间更新实现延迟传播。3. 划分树的基本操作3.1 建树Build采用递归方式自底向上构建划分树// 以区间和为例 void build(int node, int l, int r) { if (l r) { tree[node] arr[l]; // 叶子节点 return; } int mid (l r) / 2; build(node*2, l, mid); // 构建左子树 build(node*21, mid1, r); // 构建右子树 tree[node] tree[node*2] tree[node*21]; // 合并左右子树信息 }时间复杂度O(n)因为每个节点恰好被访问一次。3.2 区间查询Query查询区间 [ql, qr] 的聚合值如区间和int query(int node, int l, int r, int ql, int qr) { // 当前节点区间完全在查询区间内 if (ql l r qr) { return tree[node]; } // 当前节点区间与查询区间无交集 if (r ql || l qr) { return 0; // 对于区间和无交集返回 0 } // 当前节点区间与查询区间部分重叠递归查询左右子树 int mid (l r) / 2; int leftSum query(node*2, l, mid, ql, qr); int rightSum query(node*21, mid1, r, ql, qr); return leftSum rightSum; }时间复杂度O(log n)因为每次递归最多访问树的两条路径。3.3 单点更新Point Update更新数组某个位置的值并更新所有包含该位置的节点void update(int node, int l, int r, int idx, int val) { if (l r) { tree[node] val; // 找到叶子节点 return; } int mid (l r) / 2; if (idx mid) { update(node*2, l, mid, idx, val); } else { update(node*21, mid1, r, idx, val); } tree[node] tree[node*2] tree[node*21]; // 更新父节点 }时间复杂度O(log n)。4. 懒标记Lazy Propagation对于区间更新操作如将区间内所有元素加上一个值如果对每个元素都进行单点更新时间复杂度会退化为 O(n log n)。懒标记技术可以将区间更新的复杂度也优化到 O(log n)。4.1 懒标记原理懒标记的核心思想是延迟更新当更新操作覆盖整个节点区间时不立即更新其所有子节点而是将更新信息记录在该节点的懒标记中。只有当后续查询或更新需要访问子节点时才将懒标记向下传递push down。4.2 带懒标记的区间更新// 懒标记数组 int lazy[MAX_N * 4]; // 下传懒标记 void pushDown(int node, int l, int r) { if (lazy[node] ! 0) { int mid (l r) / 2; // 更新左子节点 tree[node*2] lazy[node] * (mid - l 1); lazy[node*2] lazy[node]; // 更新右子节点 tree[node*21] lazy[node] * (r - mid); lazy[node*21] lazy[node]; // 清空当前节点的懒标记 lazy[node] 0; } } // 区间增加操作 void rangeUpdate(int node, int l, int r, int ql, int qr, int val) { if (ql l r qr) { // 完全覆盖更新当前节点并设置懒标记 tree[node] val * (r - l 1); lazy[node] val; return; } pushDown(node, l, r); // 下传懒标记 int mid (l r) / 2; if (ql mid) { rangeUpdate(node*2, l, mid, ql, qr, val); } if (qr mid) { rangeUpdate(node*21, mid1, r, ql, qr, val); } tree[node] tree[node*2] tree[node*21]; }5. 划分树的应用场景区间求和/最值查询静态或动态数组的区间查询。区间更新给区间内所有元素加上一个值。区间赋值将区间内所有元素设置为同一个值。区间统计查询区间内满足某种条件的元素个数。二维划分树扩展至二维平面用于处理矩阵区间查询。持久化划分树可持久化线段树支持查询历史版本。6. 划分树的优缺点优点高效区间查询和更新均为 O(log n)。灵活支持多种聚合操作和、最值、GCD 等。可扩展通过懒标记支持区间更新可扩展到二维。缺点空间开销需要 O(4n) 的存储空间。实现复杂度懒标记等高级功能代码实现较为复杂。常数较大递归操作带来一定的常数时间开销。7. 代码示例完整的区间和划分树#include iostream #include vector using namespace std; class SegmentTree { private: vectorint tree; vectorint lazy; int n; void build(int node, int l, int r, vectorint arr) { if (l r) { tree[node] arr[l]; return; } int mid (l r) / 2; build(node*2, l, mid, arr); build(node*21, mid1, r, arr); tree[node] tree[node*2] tree[node*21]; } void pushDown(int node, int l, int r) { if (lazy[node] ! 0) { int mid (l r) / 2; tree[node*2] lazy[node] * (mid - l 1); lazy[node*2] lazy[node]; tree[node*21] lazy[node] * (r - mid); lazy[node*21] lazy[node]; lazy[node] 0; } } int query(int node, int l, int r, int ql, int qr) { if (ql l r qr) return tree[node]; if (r ql || l qr) return 0; pushDown(node, l, r); int mid (l r) / 2; return query(node*2, l, mid, ql, qr) query(node*21, mid1, r, ql, qr); } void rangeUpdate(int node, int l, int r, int ql, int qr, int val) { if (ql l r qr) { tree[node] val * (r - l 1); lazy[node] val; return; } pushDown(node, l, r); int mid (l r) / 2; if (ql mid) rangeUpdate(node*2, l, mid, ql, qr, val); if (qr mid) rangeUpdate(node*21, mid1, r, ql, qr, val); tree[node] tree[node*2] tree[node*21]; } public: SegmentTree(vectorint arr) { n arr.size(); tree.resize(4 * n); lazy.resize(4 * n, 0); build(1, 0, n-1, arr); } int query(int l, int r) { return query(1, 0, n-1, l, r); } void rangeUpdate(int l, int r, int val) { rangeUpdate(1, 0, n-1, l, r, val); } }; int main() { vectorint arr {1, 3, 5, 7, 9, 11}; SegmentTree st(arr); cout 区间 [1, 3] 的和: st.query(1, 3) endl; // 35715 st.rangeUpdate(1, 4, 2); // 给索引 1~4 的元素都加 2 cout 更新后区间 [1, 3] 的和: st.query(1, 3) endl; // 57921 return 0; }8. 总结划分树是解决区间查询与更新问题的利器尤其适合需要频繁进行区间操作的场景。掌握划分树的基本原理、建树、查询、更新以及懒标记技术能够帮助你在算法竞赛和工程开发中高效处理各类区间问题。在实际应用中需要根据具体问题选择合适的聚合函数并注意空间复杂度和常数优化。对于更复杂的需求还可以探索划分树的变种如权值线段树、可持久化线段树和动态开点线段树等。

相关新闻

【C++字符串】char*、const char*、char[]和std::string

【C++字符串】char*、const char*、char[]和std::string

专栏网址:https://blog.csdn.net/zhujushu/category_13112687.html 0.概述 在程序开发中,字符串操作是必不可少的功能之一。在众多编程语言中,C对字符串有着底层、较良好的支持。 C 提供了以下两种字符串表示形式: C语言风格 …

2026/10/18 8:58:11 阅读更多 →
武汉老板注意:光谷企业做展厅,别再拿“科技感“说事了

武汉老板注意:光谷企业做展厅,别再拿“科技感“说事了

‍武汉光谷,"中国光谷"这块招牌挂了快 40 年。2025 年的光谷,聚集了 1.6 万家高新技术企业、6 家国家实验室、3 个国家大科学装置。这些企业几乎家家都想做展厅,但 80% 的光谷展厅,第一句话是"科技感"。科技感…

2026/10/17 23:38:00 阅读更多 →
地信本科,应该学什么编程语言?什么阶段学?

地信本科,应该学什么编程语言?什么阶段学?

首先,一般地信本科的课程设置里就包含C、C这几种底层开发语言,但是通常不教C# ,因为C#是专门的GIS桌面开发课程,比如使用ArcEngine进行桌面端的开发。主流的GIS开发编程更倾向WebGIS或Python。C语言C语言是计算机的底层语言&#…

2026/10/18 8:58:49 阅读更多 →

最新新闻

Cursor Agent 文件写入频繁要求确认 — 排查记录与 TaoToken 配置实践

Cursor Agent 文件写入频繁要求确认 — 排查记录与 TaoToken 配置实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 19:42:30 阅读更多 →
告别Python!Spring Boot 3集成GPT-5.4,Java后端10分钟接入原生计算机操作

告别Python!Spring Boot 3集成GPT-5.4,Java后端10分钟接入原生计算机操作

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 19:42:30 阅读更多 →
工程资料员必备:四川建龙软件全套表格Word模板处理与批量生成指南

工程资料员必备:四川建龙软件全套表格Word模板处理与批量生成指南

简介:这份资源是四川建龙软件的全套工程管理表格文档,面向土建、安装、监理三大领域的施工管理人员、监理工程师及建设单位项目负责人,用于规范工程质量事故报告、开工报告、施工日志、技术核定单等环节的标准化填报流程。压缩包内共1个doc文…

2026/10/18 19:42:30 阅读更多 →
security-audit-skill 实战:Agent 安全审计技能与 findings.json 报告契约设计

security-audit-skill 实战:Agent 安全审计技能与 findings.json 报告契约设计

1. 从"security-audit-skill"这个名字说起:它到底在解决什么问题第一次看到security-audit-skill这个命名,我的直觉是:这不是一个普通的脚本,而是一个被封装成"技能"的安全审计能力单元。关键词里同时出现了s…

2026/10/18 19:42:30 阅读更多 →
Octop:面向PostgreSQL的SQL即代码工程化实践

Octop:面向PostgreSQL的SQL即代码工程化实践

1. 项目概述:Octop不是拼写错误,而是一个被严重低估的Python工程化实践样本你搜“Octop”时,大概率会撞上一堆零散的GitHub仓库、MIT学位论文附录里的脚注,或者PostgreSQL扩展文档里一闪而过的引用。它不像Django或FastAPI那样自带…

2026/10/18 19:42:30 阅读更多 →
Canvas游戏开发实战:用JS实现大鱼吃小鱼与碰撞检测

Canvas游戏开发实战:用JS实现大鱼吃小鱼与碰撞检测

1. 内容整体设计与思路拆解1.1 这个项目为什么值得做“大鱼吃小鱼”在游戏产品里算是家喻户晓的休闲玩法,看起来简单,但它其实把游戏开发中最核心的“循环”完整地串起来了:玩家输入、帧循环、碰撞检测、状态更新、画面渲染、游戏结束判定。一…

2026/10/18 19:41:29 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →