ODT 珂朵莉树

概述

珂朵莉树(Chtholly Tree / Old Driver Tree)并非特定数据结构,而是一种用平衡树(std::set)维护颜色段均摊的技巧。将值相同的连续区间合并为结点,适合含区间赋值操作的问题。起源 CF896C

结点与存储

struct Node {
  int l, r;
  mutable int v;
  Node(int il, int ir, int iv) : l(il), r(ir), v(iv) {}
  bool operator<(const Node &o) const { return l < o.l; }
};
set<Node> odt;

mutable 使 v 可在 const 迭代器中修改,避免删除重插入。

split 操作

将包含 的区间 分裂为 ,返回后者迭代器。

auto split(int x) {
  auto it = odt.lower_bound(Node(x, 0, 0));
  if (it != odt.end() && it->l == x) return it;
  --it;
  int l = it->l, r = it->r, v = it->v;
  odt.erase(it);
  odt.insert(Node(l, x - 1, v));
  return odt.insert(Node(x, r, v)).first;
}

assign 操作

区间染色:先调 split(r+1) 再调 split(l),删除中间所有段,插入新区间。

void assign(int l, int r, int v) {
  auto itr = split(r + 1), itl = split(l);
  odt.erase(itl, itr);
  odt.insert(Node(l, r, v));
}

复杂度分析

  • 数据随机时(set 实现),(链表实现)
  • 有 assign + 无遍历:均摊
  • 有遍历无 assign:可被卡到 ,依赖数据随机

例题

题目链接说明
CF896CWillem, Chtholly and Seniorious起源题,区间加/赋值/排序
P2787语文 1区间排序 + 字符统计
P1840Color the Axis区间染色模板
P4979矿洞:坍塌区间赋值 + 区间查询

参考

多平台练习

| 洛谷 | 本题单 | 竞赛基础 |
| POJ (北大) | PKU JudgeOnline | 经典题目,适合巩固 |
| HDU (杭电) | HDU OJ | 暑期多校训练 |
| Codeforces | Codeforces | 国际竞赛,适合提升 |