像潮落潮涌,送我奔向自由。|

寂静的海底

园龄:3年2个月粉丝:59关注:15

珂朵莉树学习笔记

1. 我永远喜欢珂朵莉~~


2.

珂朵莉树,又名Old Driver Tree(ODT),一种暴力维护成段区间的暴力数据结构,通常由std::set实现。


3.

珂朵莉树通常适用于区间替换(覆盖)操作,将一大段完全相同的区间维护为一个点,再放进平衡树中。

支持以下操作:

  • 1 split 分裂 :

将区间[l,r]分裂成区间[l.p1],[p,r]

  • 2 assign(Merge) 区间赋值 :

将区间[l,r]之间的区间全部替换为新区间[l,r]

  • 3 询问及其他操作

单点操作:查找到该点所在的区间并更改

区间操作:分裂两端点后暴力更改所有区间

单点查区间覆盖板子


4.

分裂即在set中查询使用std::upper_bound查询该点所在的区间,得到区间内的值,删除该区间,插入两个新区间,复杂度为O(logn)

区间赋值就是将两端点处的区间断开,再将区间内的小区间都删去,再将新区间加入,时间复杂度为O(klogn) 其中k为涉及到的区间个数。

单点操作/查询的时间复杂度同样为O(logn)

区间操作/查询的时间复杂度为O(klogn)


5. 有关时间复杂度

这玩意儿在啥时候是对的?为啥是对的?

1.区间覆盖 单点查询

势能分析:

假设一个状态的势能为此状态下不同段的个数(即set的大小)

那么区间赋值涉及到的区间数k,则势能函数必会减小至少k2

所以时间复杂度和消耗的势能是成线性关系的,又由于初始态和末态的势能都是O(n)级别的,现在需要证明势能的增量与操作数呈线性/亚线性关系。

很明显一次assign操作最多使势能增加2,复杂度为O(logn),所以势能函数的增量2×操作次数。

所以在这种情况下,珂朵莉树的复杂度是O(nlogn)


2.区间覆盖 带区间操作 数据随机

神奇 需要用到积分证明

然而此处板书太小

写不下

原始证明

可以证明段的个数x和区间覆盖的出现密度的关系k

x O(nk)

神神奇奇

set 的实现复杂度是O(nloglogn)


3.数据较水

在出题人不可刻意卡的情况下具有优秀的复杂度,可以拿来骗分。


6. 一些例题

CF896C

起源题,随机数据,区间覆盖,区间加,区间k大,区间k次方和。

CF343D

看到树上路径问题果断树剖,看到区间赋值单点查询果断ODT,在重链剖分序上使用ODT维护即可。 与大多数ODT题目一样,可用Segment Tree Beats完成。

CF1638E

因为颜色是全局加,考虑对每种颜色开一个全局加Tag (类似“郁闷的出纳员”中的全局tag) , 每个点的实际值是 a[i]+Tag[color[i]]color[i]:color1color2,则 a[i]减去Tag[color2] ,加上Tag[color1]即可,在区间替换时在单点查询区间修改的BIT上修改即可。


7.算是总结吧

由于ODT算是一种暴力数据结构,因此在时间复杂度不对的题目容易被卡,所以洛谷上好多ODT的好题都加了卡ODT的数据,再此不再列出。

但是学好ODT不失为考试骗分的一种办法,毕竟,没有暴力过不去的题嘛 /憨笑 /憨笑 /憨笑

posted @   寂静的海底  阅读(6)  评论(0编辑  收藏  举报  
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起