珂朵莉树 ODT

珂朵莉树是一种比较暴力的数据结构,一般需要数据随机,且有区间推平操作。

前置知识

set(STL,应该都懂吧)

算法用途

维护数组,支持区间推平加其他操作。

算法复杂度

时间

O ( n log ⁡ 2 n ) O(n\log ^2n) O(nlog2n)

空间

O ( n ) O(n) O(n)

算法实现

储存

因为数据随机,且有区间推平操作,所以在大部分情况下,珂朵莉树维护的数组会有相邻且相等的一段数。

我们尝试用另一种方法去记录这些数。

我们定义一个 struct,里面包含 l , r , v l, r, v l,r,v,分别表示区间左端点、右端点和区间内数的值。然后把每一段相邻且相等的数记录成一个区间,并把维护的数组中所有区间按照左端点排序放在一个 set 里面。

比如说, [ 1 , 1 , 1 , 3 , 5 , 5 , 2 , 2 ] [1,1,1,3,5,5,2,2] [1,1,1,3,5,5,2,2],就可以储存成 [ { 1 , 3 , 1 } , { 4 , 4 , 3 } , { 5 , 6 , 5 } , { 7 , 8 , 2 } ] [\{1,3,1\},\{4,4,3\},\{5,6,5\},\{7,8,2\}] [{1,3,1},{4,4,3},{5,6,5},{7,8,2}]

推平

推平操作是珂朵莉树的重点,推平操作将区间 [ l , r ] [l, r] [l,r] 里的数设成同一个值 k k k

那么在珂朵莉树中,我们只需要找出 l , r l, r l,r 所在的区间(第 i i i 个和第 j j j 个),然后将他们分别分裂成 { l i , l − 1 } , { l , r i } \{l_i,l - 1\},\{l,r_i\} {li,l1},{l,ri} { l j , r } , { r + 1 , r j } \{l_j,r\},\{r+1,r_j\} {lj,r},{r+1,rj}。最后将 l , r l,r l,r 所包括的区间全部删除,并插入一个 { l , r , k } \{l, r, k\} {l,r,k}

或者 l , r l, r l,r 在同一个区间中,那么我们把这段区间分成 { l i , l − 1 } , { l , r } , { r + 1 , r i } \{l_i,l-1\},\{l,r\},\{r+1,r_i\} {li,l1},{l,r},{r+1,ri},然后更改 { l , r } \{l, r\} {l,r} 区间即可。

其他操作

和推平操作一样,我们先把区间分裂了,然后枚举每一个被 l , r l, r l,r 包含的区间,更改或者查询他们的值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值