FhqTreap的区间翻转
学 $Fhq$ 就是为了尽量不去写某毒瘤数据结构,所以自然要来杠一杠某数据结构的经典操作:区间反转
听起来玄乎,但只需要一个小 $trick$ 就行了:把原来的区间以下标作为权值建成 $Treap$ , 这样整棵 $Treap$ 的中序遍历就是原区间.
按照这种方法建树,是进行区间操作的第一步.接下来我们考虑如何去在 $\Theta ( \log_2^{n}) $ 的时间内完成这件事.
一个基本的思路是将区间 $Split$ 为 $[1,l-1],[l,r],[r+1,n]$ 三部分,对中间的 $[l,r]$ 进行反转
反转的具体操作是从根到叶子把每个节点的左右儿子互换
显然,这样复杂度十分糟糕,甚至达到了暴力都比不上的 $\Theta ( n \times \log_2{n} )$
所以,我们必须考虑去减少我们的操作次数.
这里我们借鉴一下之前学习线段树时的 $trick$ : $lazytag$ (我不信你都学平衡树了还不会线段树)
聪明的你应该已经想到了,对没错,就是通过打 $lazytag$ 来减少我们的操作,想必原理也不用赘述
(这里有个小细节,最后输出前,别忘了把所有的 $tag$ 全部下传到底)
那么什么时候去下传 $tag$ 呢 ? 聪明的你肯定也已经想到了,对,就是在 $merge$ 和 $Split$ 两个函数中,优先下传 $tag$
建树的时候,其实应该是以使用笛卡尔树的方式建树为佳,但我太懒了,就直接 $insert$ 了
$Code$ :
1 |
|