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$节点暴力进行修改和查询。
它可以支持的操作(懒得放代码了):