线段树学习
最近在学线段树,写个总结吧
定义
线段树,顾名思义,就是 以线段(区间) 为结点的树
对于一个整区间 1~n,我们用一棵线段树来表示,任意一个节点储存某一区间内所有元素的和
根节点表示(1~n),则左儿子表示区间(1,
这样,在处理区间更新,区间求和等问题时,暴力求解为
!!! 若一个区间内元素数量为N,则由其生成的线段树最多会有 4N 个节点 (注意开数组大小

实践
建树
前言说过,线段树本质上是通过二分达到
那么建树的时候,只要递归进行二分就可以,直到到达叶子节点就停止,在回溯过程中进行值的维护(有点像动态规划
int s[10000]; // 线段树数组 int a[10000]; // 原始数列数组 void buildtree(int x,int l,int r){ // 建树 // x 当前节点在数组中下标 l 当前节点代表区间的左边界 r 当前节点代表区间的右边界 if(l==r){ // 到达叶节点 s[x]=a[l]; // 更新值 return; // 叶节点无法继续递归,直接return掉 } int mid=(l+r)>>1; buildtree(x<<1,l,mid); // 左半边(注意左儿子包含中点 buildtree(x<<1|1,mid+1,r); // 右半边 s[x]=s[x<<1]+s[x<<1|1]; // 值的维护 // 可以用位运算稍稍优化,其实没什么影响 }
单点 / 区间查询
线段树对于单点上的操作其实总是更麻烦一些,但对于区间来说就要简单了
单点查询
我们知道,线段树为每个独立元素都找好了家(既有一个人的家,也包括他的所有祖宗),他把区间分割成很多部分,最小为单个元素,那么在线段树内查找单个元素,只要从根节点向下递归,直至找到目标元素所在叶节点
递归时,对于目标元素所属区间进行判断,若属于左儿子所代表的区间,则递归至左儿子区间,反之,递归至右儿子区间
int check(int x,int l,int r,int k,int w){ // x 当前下标 l 当前左边界 r 当前右边界 k 目标节点下标 w 更新值 if(l==r) return s[x];// 找到叶节点,直接返回 int mid=l+((r-l)>>1); // 开始写二分 if(k<=mid) check(x<<1,l,mid,k,w); // 如果在左儿子(注意左儿子包括中点 if(k>mid) check(x<<1|1,mid+1,r,k,w); // 如果在右儿子 }
区间查询 ——> 区间和 / 前缀和
区间查询对于线段树来说复杂度就要低了,因为线段树就是把区间堆起来 (bushi
区间查询可以解决区间和、前缀和等问题,只要更改目标区间就可以
在区间查询的时候,如果我们遇到了一个与目标区间完全重合的节点,那么直接返回这个节点储存的值
但现实中大多不会出正好重合的区间,所以我们要进行多种情况的判断
(如果当前区间与目标区间不完全重合
- 目标区间完全处于左儿子 ==> 表现为右边界小于中点

- 目标区间完全处于右儿子 ==> 表现为左边界大于中点

- 目标区间横跨左儿子和右儿子 ==> else

int calc(int x,int l,int r,int s,int t){ if(l==s&&r==t) // 到目标区间 return s[x]; // 直接返回 int mid=(l+r)/2; if(t<=mid) // 左 return calc(x*2,l,mid,s,t); else if(s>mid) // 右 return calc(x*2+1,mid+1,r,s,t); else // 跨 return calc(x*2,l,mid,s,mid)+calc(x*2+1,mid+1,r,mid+1,t); // 记得分割目标区间,左边为 l~mid 右边为 mid+1~r }
单点更新 (很简单
对于单点更新,其实 暴力 是更好的做法 ( 暴力
查询的过程和上面一样,因为是单点,更改就直接加就好了 qwq
void check(int x,int l,int r,int k,int w){ // x 当前下标 l 当前左边界 r 当前右边界 k 目标节点下标 w 更新值 if(l==r){ // 找到叶节点 s[x]+=w; // 单点更新 ( 确实很简单 return; } int mid=l+((r-l)>>1); // 开始写二分 if(k<=mid) check(x<<1,l,mid,k,w); // 如果在左儿子(注意左儿子包括中点 if(k>mid) check(x<<1|1,mid+1,r,k,w); // 如果在右儿子 s[x]=s[x<<1]+s[x<<1|1]; // 更新之后需要维护,来确保正确性 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)