参考课程是我高中信息竞赛邱老师的课程。
【18-1 线段树:建树与区间查询】 https://www.bilibili.com/video/BV1cJ4m1u7yc/?share_source=copy_web\&vd_source=2c56c6a2645587b49d62e5b12b253dca
【线段树:单点修改、区间修改】 https://www.bilibili.com/video/BV1sarmYQEmt/?share_source=copy_web\&vd_source=2c56c6a2645587b49d62e5b12b253dca
【线段树习题精讲 P2471 降雨量】 https://www.bilibili.com/video/BV1Bt5kzNENN/?share_source=copy_web\&vd_source=2c56c6a2645587b49d62e5b12b253dca
线段树能完成树状数组的所有功能,但是树状数组不能完成线段树的所有功能。虽然树状数组的实现和板子会简单很多。
需要完整ACM CSP板子可以去资源搜,我设置的0积分,如果要钱来B站私我。
线段树(穿插有修改和查询)
预处理区间,拼凑查询的区间。4,7就可以通过4,56,7拼凑出来。

存储上使用一个数组存储这个区间的最大值即可,不用存区间范围,因为范围可以求出来。
对于每个节点p而言,其最大值为其左右子节点的最大值dp=max(dp\<\<1,d(p\<\<1)\|1


采用类堆索引,p节点的子节点是p*2 p*2+1
数组要开多大?4N个

建树

采用类堆索引,p节点的子节点是p*2 p*2+1。
这个结构告诉我们,buildtree要传入三个参数 区间范围st和当前节点编号p

区间查询
输入是查询目标LR 查询区间是sm,如果有就直接返回。如果没有就看LR是否被m切为两半,如果有部分在左侧(L<=m)那么去左边递归找最大值,否则去右边找最大值。

复杂度分析

小结


线段树单点修改



线段树区间修改(懒标记)

区间如果下传到每个节点修改成本太高,考虑修改部分节点。
只用改两个节点,就是边界节点。其余包含在LR内的节点打上懒标记。【类似前缀和的思想,中间的非边界节点同时增加,最大值关系不变,只有边界节点最大值可能改变】
对于被包含在LR内部的最值,直接+=修改值v,打上懒标记lazyp+=v;
对于在边界的节点,比如修改3,7时的1,4区间,就包含了边界3.此时就需要跟新这个节点。
更新边界节点要递归更新其左右子树,最后再更新自身,自身依旧是左右子树取最大值。

其中这个push_down的函数就是将懒标记下传的意思。
将懒标记lazyp传递给左右子树,也就是对其dp\<\<1 d(p\<\<1)\|1+=lazyp加上当前节点的标记值。加完之后清空当前节点的标记值。


树状数组
【树状数组-单点修改、区间查询】 https://www.bilibili.com/video/BV1Rv5YzBEDP/?share_source=copy_web\&vd_source=2c56c6a2645587b49d62e5b12b253dca
【树状数组习题精讲P1908逆序对】 https://www.bilibili.com/video/BV1s4LezoEtH/?share_source=copy_web\&vd_source=2c56c6a2645587b49d62e5b12b253dca
【树状数组习题精讲 P1966火柴排队】 https://www.bilibili.com/video/BV173VtzdEpj/?share_source=copy_web\&vd_source=2c56c6a2645587b49d62e5b12b253dca
【树状数组-区间修改、单点查询】 https://www.bilibili.com/video/BV1tXGRzUEao/?share_source=copy_web\&vd_source=2c56c6a2645587b49d62e5b12b253dca
【树状数组-区间修改、区间查询】 https://www.bilibili.com/video/BV1vfVzzpErb/?share_source=copy_web\&vd_source=2c56c6a2645587b49d62e5b12b253dca