old driver tree

ODT简介

ODT(old driver tree 老驱动树)又名珂朵莉树

是由$codeforces$上一位叫做$ODT$的用户提出的一种基于平衡树的暴力数据结构。(实际上就是 $lxl$

这个数据结构的玄妙之处在于它并没有稳定的时间复杂度,因此只有在数据随机/水的情况下才会有较好的表现。

实现前提&&实现原理

前提是必须要有区间覆盖操作数据较随机/水

实现原理:将元素相同的区间推平一起处理,即如果区间$[l,r]$中的所有数$[a_l,a_{l+1}…a_r]$全部相同的话就将这个区间的信息用一个节点表示。

从上述描述可以看出这个数据结构是非常暴力玄学

初始化

然后对于每段区间我们可以用一个三元组$[l,r,v]$来表示它的左/右端点和整个区间的值,然后对于这些区间的信息可以用一个$set$来维护。

下面谈谈$ODT$两个重要的操作$split$和$assign$

split操作

$ODT$的$split$函数$split(pos)$表示把$pos$所在的这个区间$[l,r,v]$分成$[l,pos-1,v]$和$[pos,r,v]$并且返回后者的迭代器。

实现很简单直接二分找出$pos$所在的区间然后加几个小特判。


assign操作

$ODT$最核心的操作$assign$,$assign(l,r,v)$表示把区间$[l,r]$全部赋值为$v$并且会将这$r-l+1$个点合并成一个$ODT$节点插入到$ODT$中,由于数据随机的时候$ODT$中节点会快速减少,因此$ODT$复杂度此时十分接近$O(n\log n)$
具体实现可以通过上面提到的$split$函数。


其它操作

至此,与$ODT$相关的操作已经基本讲完了。

剩下的操作与$ODT$本身关系并不大,相当于就是遍历每一个$ODT$节点暴力进行修改和查询。
它可以支持的操作(懒得放代码了):

区间第k小

区间加

区间所有数的k次方和

区间…