线段树与树状数组的基本概念
- 线段树的定义与核心思想
基于二叉树结构,支持区间查询与更新操作,适用于动态维护区间信息。 - 树状数组的定义与核心思想
基于二进制索引的低位技术,高效处理前缀和与单点更新,空间复杂度更低。
数据结构设计对比
- 存储结构差异
线段树使用显式二叉树或数组模拟,需 $O(4n)$ 空间;树状数组使用紧凑数组,仅需 $O(n)$ 空间。 - 操作复杂度分析
线段树查询/更新为 $O(\log n)$,支持任意区间操作;树状数组查询/更新为 $O(\log n)$,但区间操作受限(如需差分技巧)。 - 功能支持范围
线段树支持区间覆盖、最值、求和等复杂操作;树状数组专注前缀和与单点修改衍生功能。
典型应用场景
- 线段树适用场景
动态区间最值(如RMQ)、区间修改(如延迟标记)、二维空间划分(如矩形面积并)。 - 树状数组适用场景
高频单点更新与前缀统计(如逆序对计数)、离线查询优化(如扫描线算法辅助)。
实现示例与性能优化
- 线段树模板代码片段
struct SegmentTree { int l, r, sum; int lazy; // 延迟标记 void update(int val) { sum += (r - l + 1) * val; lazy += val; } } tree[N<<2]; - 树状数组模板代码片段
int BIT[N]; void update(int x, int val) { while (x <= n) BIT[x] += val, x += x & -x; } - 优化技巧
线段树动态开点节省空间;树状数组扩展实现区间加减(结合差分数组)。
选择策略与总结
- 数据结构选择依据
根据问题需求权衡:功能复杂性(线段树) vs 代码简洁性与效率(树状数组)。 - 混合使用案例
结合线段树的区间处理能力与树状数组的低常数,解决多维问题(如三维偏序)。