首页 > 其他分享 >珂朵莉树

珂朵莉树

时间:2023-12-16 20:55:59浏览次数:22  
标签:node ll tree pos 朵莉树 split 节点

珂朵莉树的适用范围是具有区间赋值操作且数据随机的题目。

珂朵莉树的思想在于随机数据下的区间赋值操作很可能让大量元素变为同一个数,所以我们以三元组<l,r,v>的形式保存数据(区间[l,r]中的元素的值都是v):

struct node
{
    ll l, r;
    mutable ll v; // 这里mutable要写不然可能会CE
    node(ll l, ll r, ll v) : l(l), r(r), v(v) {} // 构造函数
    bool operator<(const node &o) const { return l < o.l; } // 重载小于运算符
};

用set存储三元组:

set<node> tree;

set会保证内部元素有序(便于插入、删除和查询),而mutable使得当整个结构体为const时,标为mutable的成员仍可变(便于区间加)。

  • split():区间操作可能会需要把原本连续的区间断开
auto split(ll pos)
// 若不支持C++14,auto须改为set<node>::iterator
{
    auto it = tree.lower_bound(node(pos, 0, 0)); // 寻找左端点大于等于pos的第一个节点
    // 若不支持C++11,auto须改为set<node>::iterator
    if (it != tree.end() && it->l == pos) // 如果已经存在以pos为左端点的节点,直接返回
        return it;
    it--; // 否则往前数一个节点
    ll l = it->l, r = it->r, v = it->v;
    tree.erase(it); // 删除该节点
    tree.insert(node(l, pos - 1, v)); // 插入<l,pos-1,v>和<pos,r,v>
    return tree.insert(node(pos, r, v)).first; // 返回以pos开头的那个节点的迭代器
                                               // insert默认返回值是一个pair,第一个成员是我们要的
}

原来:

执行split(4)后:(<2,4,2>变成<2,3,2>和<4,4,2>)

  • assign():区间赋值操作
void assign(ll l, ll r, ll v)
{
    auto end = split(r + 1), begin = split(l); // 顺序不能颠倒,否则可能RE
    tree.erase(begin, end); // 清除一系列节点
    tree.insert(node(l, r, v)); // 插入新的节点
}

即把范围内的节点全部删除,然后换上新的(范围更大的)节点。

注意求end和begin的顺序不能颠倒,因为split(end)可能把begin原来所在的节点断开。

标签:node,ll,tree,pos,朵莉树,split,节点
From: https://www.cnblogs.com/yhstsy/p/17908354.html

相关文章

  • 柯学家——珂朵莉树 学习笔记
    柯学家——珂朵莉树学习笔记珂朵莉树(ChthollyTree),又名老司机树ODT(OldDriverTree)。起源自lxl的CF896CWillem,ChthollyandSeniorious。前置知识:std::set。思想将区间用set维护,每次对一个区间进行操作的时候,就将这个区间分离(split)出来。复杂度的保证依靠推平......
  • 颜色段均摊(珂朵莉树)
    珂朵莉树的复杂度分析CF896C珂朵莉树起源题LG4979矿洞:坍塌珂朵莉树可以在区间覆盖时顺便把左右的同色段合并了,这样任意时刻相邻的两段都不同色本题询问时判断\([l,r]\)是否同色就可以通过判断\([l,r]\)是否在同一段实现了https://www.luogu.com.cn/problem/P8146......
  • 珂朵莉树——优雅的暴力
    珂朵莉树引入珂朵莉树(ChthollyTree),又名老司机树(OldDriverTree)。起源于CF896C。这种想法的本质是基于数据随机的「颜色段均摊」,而不是一种数据结构。前置需要了解STL的set的基本用法。比如:insert(x) 当容器中没有等价元素的时候,将元素x插入到 set 中。er......
  • 珂朵莉树(ODT)
    处理区间赋值问题的神器!珂朵莉树的实现非常简单(baoli),建树时把区间的左右端点和权值作为一个节点全扔到std::set(或者链表)中维护即可split:核心操作之一,将一段区间提取出来,在此之上进行一些操作assign:核心操作之二,也是降低珂朵莉树时间复杂度的重要操作,把一段区间推平赋值,......
  • 珂朵莉树
    区间赋值的数据结构都可以骗分,在数据随机的情况下,复杂度可以保证。时间复杂度:O(nloglogn)structODT{ structnode{ intl,r; mutableLLv; node(intl,intr=-1,LLv=0):l(l),r(r),v(v){} booloperator<(constnode&o)const{returnl<o.l;} }; s......
  • 【模板】ODT | Old Driver Tree | 珂朵莉树
    postedon2021-04-0220:38:49|under学术|source这个东西本身不常用,但是这个维护连续段的写法很常用。标签:暴力、数据结构、std::set#include<set>template<cla......
  • 珂朵莉树学习笔记
    ##什么是珂朵莉树?**珂朵莉树**,别名颜色段均摊、ODT,它是$2017$年一场CF比赛中提出的数据结构,因为题目背景主角是《末日时在做什么?有没有空?可以来拯救吗?》的主角珂朵莉,......
  • 珂朵莉树浅析
    珂朵莉树浅析0.关于珂朵莉中国珂学院1.珂朵莉树实现珂朵莉树(也称OldDriverTree),是一种暴力数据结构,其代表的操作有:区间推平(将区间\([l,r]\)的数修改为\(x\));......
  • 珂朵莉树
    严格来说,珂朵莉树主要的用处是骗分——OIWikiclassODT{structnode{intl,r;mutablellv;node(constint&il,constint&ir,......
  • 浅谈珂朵莉树
    珂朵莉最可爱了。好了不废话了,直接开始珂朵莉树。什么是珂朵莉树珂朵莉树,又叫老司机树,英文名字\(\text{ODT}\),是一种支持区间平推的乱搞数据结构,在数据随机时表现十分......