都是Splay比较常见的操作,平衡树节点维护是一个量:左右儿子,子树大小,节点代表的值(对于非哨兵来说,值等于输入的 c c c;对于哨兵来说,值等于 0 0 0),节点代表的副本值(对于非哨兵来说,副本值等于值;对于哨兵来说,副本值等于 − 1001 -1001 −1001),子树代表的区间从左/右开始的最大和,子树代表的区间的总和以及最大和,翻转懒标记,修改懒标记
注意事项:
1.副本值的作用:由于操作六要求非空,所以当数列中(除哨兵)的数都为负的时候,要输出数列中的最大值;而副本值就可以进行判断
2.两个懒标记的下放没有顺序要求
3.平衡树的一个很好的调试的方法,就是按照中学遍历遍历平衡树并且输出,看是否是理想的数列
4.内存回收:如果每次新建一个节点会MLE;考虑到删除的数的数量不会多于插入的数的数量,所以每次删除的时候我们遍历删除的子树,将所有节点的编号放入一个栈中,然后每次新建节点的时候编号从栈里面取,时间复杂度仍然优秀;如果利用指针的new
操作进行内存回收,那么一定要一开始就new
完(指new int[N]
),而不要需要的新建的时候就new
一下,这样子会超时间(可以认为前者的时间复杂度为
O
(
1
)
O(1)
O(1),后者的时间复杂度为
O
(
n
)
O(n)
O(n)),但如果最开始new
完就没办法内存回收了