题意
要求维护一个数列,支持以下操作:
其中,插入总数字个数小于 4 e 6 4e6 4e6,每个数在 [ − 1000 , 1000 ] [-1000,1000] [−1000,1000] 范围,保证每次操作合法。
分析
这道题是一道 S p l a y Splay Splay 码农题,细节颇多,让我们一个一个操作分析。
- 插入操作
我们可以先对要插入的这 t o t tot tot 个数建树,得到树根 t r t trt trt,再将 t r t trt trt 插入原序列。 - 删除操作
就是普通的删除,将 r + 1 r+1 r+1 旋到根,将 l − 1 l-1 l−1 旋到根的右儿子,然后 l − 1 l-1 l−1 的儿子置为 0 0 0 即可。(这里的 l , r l,r l,r 指的是排名,不是值) - 修改操作
同理,只要给 l − 1 l-1 l−1 的儿子加个 t a g tag tag 即可。 - 翻转操作
同理,也是加个 t a g tag tag。但需要注意的是,翻转的时候,需要将最大前缀和和最大后缀和交换! - 求和操作
过于简单,因此省略。 - 最大子列和
这个和 小白逛公园 的原理是一样的,就是利用分治,维护区间的最大子段和,区间和,区间最大前缀和,区间最大后缀和。
在这里,我们定义,最大前缀和和最大后缀和可以为空,子段和不能为空。
然后就是码码码…
借此题总结一下 Splay 的一些技巧和注意点
- S p l a y Splay Splay 支持的操作包括区间翻转,区间删除,区间平移,区间交换,线段树能实现的功能 s p l a y splay splay 都能实现。
- 先在首尾建两个哨兵节点,防止 s p l a y splay splay 操作出错,有时候要给哨兵节点赋初始值
- 对于位置 p p p,它的排名为 p + 1 p+1 p+1(因为有哨兵节点),它对应的节点为 k t h ( r o o t , p + 1 ) kth(root, p + 1) kth(root,p+1);节点