传送门->
这题没什么好说的……小清新数据结构题……并不对劲的人太菜了,之前照着标程逐行比对才过了这道题,前几天刚刚把这题一遍写对……
其实这题应该口胡很容易。操作1,2,3,4,5就是普通的splay支持的那些操作。操作6要转一个小弯,对于每个点记lmax,rmax,xmax,分别表示贴左边界的最大连续子段和(可能为空)、贴右边界的最大连续子段和(可能为空)、最大子段和(不能为空)。现在考虑将lson[u]和rson[u]子树对应的序列的lmax,rmax,xmax经过一些神奇的操作合并,得到u的子树对应的这些值。lmax[u]:跨越u时是左边整段+key[u]+右边lmax;不跨越时是左边的lmax。rmax[u]:同上。xmax[u]:跨越u时是左边贴右边界+右边贴左边界+key[u];不跨越时左边、右边的xmax二选一。
听上去这题已经口胡完了,但是调它的路还长这呢。要注意几点小小的问题:
1.一开始建树时不要一个个插入,可以每次取中点作为根,再递归处理左右两边,这样会形成更加平衡的树。会发现操作1是插入一个序列,可以类似地先将这个序列建成平衡的树。(不这么做可能TLE)
2.发现数据略坑,无脑新建点会需要4*10^6个点。但是只会有5*10^5个点被用到,所以对于那些删掉的点,可以将它们的编号存在【随便什么简单数据结构】里,用的时候再拿出来。(不这么做会MLE或RE)
3.在做2时,假设将编号x存到了【随便什么简单数据结构】里,发现它被删除前的父亲、儿子、lmax、rmax等一系列信息还在,注意要记得初始化。(不这么做当然会WA)
4.在pushdown时,发现当有一段被改成同一个数后就不用管翻转标记了。(不这么做会常数极大)
5.pushup/down时懒得判某个儿子为0怎么办?在pushup/down前后强行将编号为0的点的各种值全部设置为初始值!(不这么做会写烦)
6.在做5时,xmax[0]=-inf,其余都为0。(不这么做会WA)
7.对于某点打上修改标记时,pushdown前它的左、右儿子都没有改变,这时pushup就会得到修改前的答案。不能盲目地pushup。(不这么做会WA)
8.pushdown翻转标记时,记得交换lmax,rmax。(不这么做会WA)
#include
#include
#include
#include
#include
#include
#include
#include
最后祝您身体健康,再见。