线段树总结
线段树
你说的对,但线段树是一种用 的大常数复杂度+略微的卡常下技巧=AC 的妙妙数据结构。
线段树是基于分治与二叉树的在线工具,可以维护区间信息,但比树状数组能够维护的东西更多。
线段树虽然能够维护的东西更多,但也有一些特别显著的缺点:
- 代码量过长。
- 查错不好查。
- 大常数超时。
线段树其所对应的时空复杂度对应
在线段树中,节点的左儿子为
一些易错点
线段树数组要乘
原因:
线段树是一种二叉树结构,其结构若为完全二叉树,则其所需空间为:
但是实际应用中最后一层远远铺不满,所以最后一层的编号用不全,最坏情况是只用了最后一层的最后一个,为上一层编号再
线段树在修改与查询时,查询区间不变
比较常犯的一个错误,因为写 build(int p,int l,int r)
时,l
代表当前区间左端点,r
代表区间右端点,所以递归时要 build(p*2,l,mid)
与 build(p*2+1,mid+1,r)
。
但是在修改与查询中 ask(int p,int l,int r)
中,l
、r
代表查询区间的左右端点,算是定值,不能更改。
在询问与修改中,
很明显的一个错,但总是查不出来。
应该为
在修改中,为往上更改节点所存的值。
不必多言,注意了也经常错。
在建树(build
函数)时,没有 return
当你犯过一次并为此投入
To Be Continued
以下提供线段树查错思路
以上四种错误(除第
如果不是
建议:
- 先查线段树数组是否
。 - 查询问与更改时,函数参数是否发生了不对的变化,见上第
点。 - 同时检查第
点。 - 最后再看
build
函数。
例题
【线段树模板题】序列操作1
板子。
F - Second Largest Query
进行分类讨论,我们也可以选择排序后选前两大,思维上难度较小。
A Simple Problem with Integers
懒惰标签板子。
维护序列-区间乘与区间加
维护两个懒惰标签,形如:
区间加可直接加,区间乘需要将
花神游历各国
结论题,注意到
注意:
特殊判断
无聊的序列
差分之,操作一等效为区间加;操作二等效为区间求和。
E - Simple String Queries
线段树中维护 bitset
。
G - Smaller Sum
线段树中维护 vector
。