c++怎么实现线段树数据结构_c++ 区间查询与单点修改逻辑【指南】
发布时间 - 2025-12-26 00:00:00 点击率:次线段树核心结构体采用数组式存储,tree大小为4*n,根节点编号为1,含n和tree成员;单点修改需递归定位叶子并回溯更新;区间查询须分无交、全含、部分重叠三种情况处理。
线段树的核心结构体怎么写
线段树在 C++ 中最常用的是数组式(堆式)存储,而非指针式——因为避免动态分配开销、缓存友好、代码简洁。关键点是:tree 数组大小至少为 4 * n(n 是原始数组长度),这是安全上界,能覆盖所有可能节点。
结构体里通常只存区间端点和值,不建议塞太多字段。例如支持「区间求和 + 单点修改」时,tree[i] 存的是对应区间的和:
struct SegmentTree {
vector tree;
int n;
SegmentTree(int size) : n(size), tree(4 * size, 0) {}
void build(const vectorzuojiankuohaophpcnintyoujiankuohaophpcn& arr, int node = 1, int l = 0, int r = -1) {
if (r == -1) r = n - 1;
if (l == r) {
tree[node] = arr[l];
return;
}
int mid = (l + r) / 2;
build(arr, node * 2, l, mid);
build(arr, node * 2 + 1, mid + 1, r);
tree[node] = tree[node * 2] + tree[node * 2 + 1];
}};
注意:这里用 node * 2 和 node * 2 + 1 表示左右子节点,根节点编号为 1(不是 0),这是标准堆式约定;若用 0 作根,则左子为 2*node+1,容易
混淆,不推荐初学使用。
单点修改的递归逻辑怎么写才不出错
单点修改本质是「从根往下找唯一包含该位置的叶子,改完再向上更新父节点」。常见错误是边界判断写反、忘记回溯更新、或误把 l == r 当成递归终止但没处理好 mid 计算。
-
update(pos, val, node, l, r) 的 pos 是原始数组下标(0-based),必须严格落在当前 [l, r] 内
- 递归时只进一个分支:若
pos 走左,否则走右
- 更新完子树后,一定要执行
tree[node] = tree[left] + tree[right],漏这步会导致查询结果错误
示例实现:
void update(int pos, long long val, int node = 1, int l = 0, int r = -1) {
if (r == -1) r = n - 1;
if (l == r) {
tree[node] = val;
return;
}
int mid = (l + r) / 2;
if (pos <= mid) {
update(pos, val, node * 2, l, mid);
} else {
update(pos, val, node * 2 + 1, mid + 1, r);
}
tree[node] = tree[node * 2] + tree[node * 2 + 1];
}区间查询为什么不能直接用 (l, r) 套公式
区间查询不是数学公式代入,而是递归拆解覆盖过程。典型错误是认为「只要当前节点区间被查询区间完全包含,就直接返回 tree[node]」,却忽略:若查询区间跨中点,必须拆成两段分别查,再合并结果。
正确逻辑分三种情况:
- 当前区间
[l, r] 与查询区间 [ql, qr] 无交集 → 返回单位元(如求和返回 0)
- 当前区间被完全包含 → 直接返回
tree[node]
- 部分重叠 → 递归查左右子树,返回二者之和
注意:边界比较必须用 ,不是 ;且查询函数应返回值,不是 void:
long long query(int ql, int qr, int node = 1, int l = 0, int r = -1) {
if (r == -1) r = n - 1;
if (qr < l || r < ql) return 0; // 无交集
if (ql <= l && r <= qr) return tree[node]; // 完全包含
int mid = (l + r) / 2;
return query(ql, qr, node * 2, l, mid) +
query(ql, qr, node * 2 + 1, mid + 1, r);
}为什么 build / update / query 都要手动传参而不是封装成类成员方法
初学者常把 l、r 提成类成员变量,结果发现多组查询会互相污染。根本原因是:线段树每个递归调用都依赖当前节点对应的区间范围,这个范围随调用栈深度变化,无法全局固定。
所以必须让 l 和 r 作为参数层层传递。虽然看起来啰嗦,但这是最清晰、最不易出错的方式。C++17 后可用 std::optional 或默认参数简化接口(如上面示例用 r = -1 触发初始化),但底层逻辑不变。
另一个易忽略点:所有操作的时间复杂度都是 O(log n),但常数较大。如果只是做单点改 + 单点查,用普通数组就够了;只有真需要「任意区间求和/最小值/最大值」时,线段树才有意义。
# node
# 栈
# c++
# 为什么
# 封装
# 成员变量
# 结构体
# 递归
# void
# 指针
# 数据结构
# 接口
# 堆
# 单点
# 这是
# 子树
# 的是
# 三种
# 都是
# 太多
# 都要
# 才有
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何在万网ECS上快速搭建专属网站?
Internet Explorer官网直接进入 IE浏览器在线体验版网址
Laravel如何构建RESTful API_Laravel标准化API接口开发指南
独立制作一个网站多少钱,建立网站需要花多少钱?
Laravel Sail是什么_基于Docker的Laravel本地开发环境Sail入门
Laravel安装步骤详细教程_Laravel环境搭建指南
如何生成腾讯云建站专用兑换码?
Laravel如何使用API Resources格式化JSON响应_Laravel数据资源封装与格式化输出
Laravel如何使用Seeder填充数据_Laravel模型工厂Factory批量生成测试数据【方法】
如何自定义safari浏览器工具栏?个性化设置safari浏览器界面教程【技巧】
网站优化排名时,需要考虑哪些问题呢?
WordPress 子目录安装中正确处理脚本路径的完整指南
Laravel API路由如何设计_Laravel构建RESTful API的路由最佳实践
Laravel用户认证怎么做_Laravel Breeze脚手架快速实现登录注册功能
Laravel如何实现用户注册和登录?(Auth脚手架指南)
Laravel的HTTP客户端怎么用_Laravel HTTP Client发起API请求教程
Midjourney怎么调整光影效果_Midjourney光影调整方法【指南】
专业商城网站制作公司有哪些,pi商城官网是哪个?
laravel怎么实现图片的压缩和裁剪_laravel图片压缩与裁剪方法
ChatGPT怎么生成Excel公式_ChatGPT公式生成方法【指南】
详解CentOS6.5 安装 MySQL5.1.71的方法
Win11怎么设置默认图片查看器_Windows11照片应用关联设置
Java Adapter 适配器模式(类适配器,对象适配器)优缺点对比
laravel怎么为API路由添加签名中间件保护_laravel API路由签名中间件保护方法
详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)
香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南
作用域操作符会触发自动加载吗_php类自动加载机制与::调用【教程】
如何用5美元大硬盘VPS安全高效搭建个人网站?
轻松掌握MySQL函数中的last_insert_id()
Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转
Laravel如何操作JSON类型的数据库字段?(Eloquent示例)
Laravel怎么解决跨域问题_Laravel配置CORS跨域访问
如何在万网自助建站中设置域名及备案?
EditPlus中的正则表达式 实战(2)
Laravel怎么生成二维码图片_Laravel集成Simple-QrCode扩展包与参数设置【实战】
英语简历制作免费网站推荐,如何将简历翻译成英文?
再谈Python中的字符串与字符编码(推荐)
Laravel Debugbar怎么安装_Laravel调试工具栏配置指南
Python正则表达式进阶教程_复杂匹配与分组替换解析
EditPlus中的正则表达式 实战(4)
使用豆包 AI 辅助进行简单网页 HTML 结构设计
网站制作软件免费下载安装,有哪些免费下载的软件网站?
如何在Windows环境下新建FTP站点并设置权限?
网站建设保证美观性,需要考虑的几点问题!
js实现点击每个li节点,都弹出其文本值及修改
Laravel的.env文件有什么用_Laravel环境变量配置与管理详解
Laravel如何实现本地化和多语言支持_Laravel多语言配置与翻译文件管理
*服务器网站为何频现安全漏洞?
Laravel Seeder填充数据教程_Laravel模型工厂Factory使用
HTML5打空格有哪些误区_新手常犯的空格使用错误【技巧】


混淆,不推荐初学使用。