【日志】珂学——珂朵莉树

珂朵莉树

珂学

珂朵莉树(或者老司机树)起源于CF896C
由于之前做到每一组数据都要另外开数据结构,所以现在一些东西就会写为class包装

前置知识点

  • STL中set的使用(list也行,但是效率差点)
    • set的排序规则
    • insert
    • erase
    • lower_bownd
  • 暴力

使用

珂朵莉树通过直接对区间进行暴力维护。不同于线段树或者树状数组对于区间的维护,珂朵莉树相当于直接把区间拆出来进行修改。

下面的代码基于CF896C。

定义

珂朵莉树的定义如下:

// using ll = long long;
class ODT {
   
	private:
    	class Node {
   
          	int l, r;
            mutable ll val;
            Node(int l = 0, int r = 0, ll val = 0) : l(l), r(r), val(val) {
   }
            bool operator < (const Node &a) const {
   
                return l < a.l;
            }
        };
    	set<Node>tr;
    public:
		void insert(int l, int r, int val);
		auto split(int pos);
		void assign(int l, int r, ll val);
		auto work(int l, int r, ...);
};

珂朵莉树是对区间的暴力维护,需要重载小于号(或者写个比较函数,只要像上面那个一样就行)(Node是想不到名字就起的,也可以改为Segment)。而后面的set就是珂朵莉树的核心。

关于mutable关键字

mutable意为可变的,也就是说,加上这个关键字可以直接对里面的val进行修改,而无需清除再插入

下面还有几个操作。

insert

其实这个操作仅仅是把区间插入set里面(因为没有的区间要插入),不过因为用class包装所以需要多一个insert。

void ODT::insert(int l, int r, int val) {
   
    tr.insert(Node(l, r, val));
}

split

珂朵莉树的第一个核心操作。

这个操作就是直接暴力的把一个区间(根据区间左端点)拆出来。

auto ODT::split(int pos) {
   
    auto it = tr.lower_bownd(Node(pos));
    // 找到一个有效的区间,而且这个区间左端点刚好是位置
    if (it != tr.end() && it->l == pos) {
   
        return it;
    }
    // 到这里,说明找的区间位置偏右了点
    -- it;
    int l = it->l, r = it->r;
    ll val = it->val;
    // 暴力分裂
    tr.erase(it);
    tr.insert(Node(l, pos - 1, val));
    return tr.insert(Node(pos, r, val)).first;
}
set的insert操作的first

set的insert操作中会返回一个pair。其中first为指向插入内容的迭代器。由于分裂的目的就是为了提出左端点为pos的区间,所以要返回这个玩意。

assign

这个是珂朵莉树的第二个关键操作。

这个操作就是简单暴力地,将l到r范围内的所有区间暴力删掉,然后新建一个区间l到r,值改为val

void ODT::assign(int l, int r, ll val) 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值