zkw线段树学习笔记
-
zkw线段树是什么
zkw线段树,顾名思义,是一种线段树。
他是线段树的非递归形式,虽然没递归版线段树那么通用,但它的常数与码量吊打递归版线段树。 -
zkw线段树的构造
说了那么多,不会写也没用啊。
递归式线段树自上往下遍历,即从根节点到叶节点,再回到根节点。
zkw则正好相反,直接从叶节点到根节点。
这就要我们记录下每一个叶节点的位置。
但在一般情况下不太好记录。
如图,每个叶节点的位置不太规律。
但有一种特殊情况。
也就是叶节点的个数是2的次幂的时候,线段树是一棵满二叉树。
zkw线段树的方法就是在原数列后面补0,使其变为满二叉树的形态。
这样叶子节点就很好找。
构建代码如下:int M,tr[N<<2],n;//n为原始数据个数,tr为线段树,M为填充后数据个数 void build(){ for(M=1;M<=n;M<<=1); //根据需要自行补充 }
-
zkw线段树单点操作
可以发现,既是填充后数据个数,也是填充后第一个数据的编号,将其留空(有用)
因此,原数据第个对应的叶节点编号为
单点修改就在叶节点直接修改,向上pushup//单点增加代码 void modify(int pos,int x){ pos+=M;tr[pos]+=x;pos>>=1; while(pos){ tr[pos]=tr[pos<<1]+tr[pos<<1|1]; } }
单点查询更加简单。相信不用说了。
-
zkw线段树区间操作
区间查询就当然不能一个一个查了这和暴力有什么区别
正解:设两个指针,,初始时分别指向,的位置(0的位置派上用场了)。
然后同步向上跳,父亲节点相同(即成为兄弟时)时停止向上跳。
如果为父亲的左儿子,那将兄弟的数据合并。
因为肯定包含,且不为兄弟,所以兄弟数据在范围内。
同理,如果为父亲的右儿子,那将兄弟的数据合并。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现