这道题目涉及了伸展树的分裂特点。
这里注意,当我们要对伸展树做区间分裂操作的时候,我们要添加开始于结尾两个点,用于防范边界情况。输出时特殊判断即可。具体做法是在build建树之前先手动给root一个值0然后给root的右儿子一个值n+1,这样我们就形成了一个区间【0,n+1】,然后我们在将要建立的1-n这棵树放在root的右儿子的左子树上。这里一定要理解。因为以后我们对伸展树的区间操作都是这种方法,假如要提取区间【a,b】那么我们就要将a-1旋转到根,b+1旋转到根的右儿子。然后很显然,右儿子的左子树就是我们所要找的区间。
CUT a,b,c 这个操作要求我们将区间[a,b]分裂出来然后添加在第c个数后面。具体取法与上面相同。这里说一下合并到c之后的方法,做法就是将C旋转到root,然后将右子树的最小值旋转到右子树的根,然后我们在将区间插入右子树的左子树。
FLIP a,b 区间翻转。
这里要注意下。我上面说的a,b都是从左往右第a或第b个数。
总结一下关键字:区间 ,root的右儿子的左子树。
我的splay。。。好长的代码量啊,,,能用treap我一定不用splay。。。。。
Play with Chain
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2429 Accepted Submission(s): 980
At first, the diamonds on the chain is a sequence: 1, 2, 3, …, n.
He will perform two types of operations:
CUT a b c: He will first cut down the chain from the ath diamond to the bth diamond. And then insert it after the cth diamond on the remaining chain.
For example, if n=8, the chain is: 1 2 3 4 5 6 7 8; We perform “CUT 3 5 4”, Then we first cut down 3 4 5, and the remaining chain would be: 1 2 6 7 8. Then we insert “3 4 5” into the chain before 5th diamond, the chain turns out to be: 1 2 6 7 3 4 5 8.
FLIP a b: We first cut down the chain from the ath diamond to the bth diamond. Then reverse the chain and put them back to the original position.
For example, if we perform “FLIP