java解析odt_[转]我的数据结构不可能这么可爱!——珂朵莉树(ODT)详解

参考资料:

Chtholly Tree (珂朵莉树) (应某毒瘤要求,删除链接,需要者自行去Bilibili搜索)

在全是珂学家的珂谷,你却不知道珂朵莉树?来跟诗乃一起学习珂朵莉树丫~

(挑战用最短的篇幅讲清楚一个毒瘤数据结构)

1、珂朵莉是什么?

珂朵莉·诺塔·瑟尼欧里斯是轻小说及改编动画《末日时在做什么?有没有空?可以来拯救吗?》中的女主角,五位成体妖精兵之一。最强圣剑“瑟尼欧里斯”的适合者。在第28号浮游岛上意外跌落而与威廉相遇,并受到他的帮助。 但是知道了珂朵莉对你学习珂朵莉树并没有什么帮助。

2、珂朵莉树是什么?

珂朵莉树又称老司机树(Old Driver Tree),可能是因为发明者是一个珂学家所以发明了这个数据结构?

废话到此结束。

珂朵莉树是基于C++STL库中的set的数据结构。与线段树、平衡树等树形结构类似,珂朵莉树是用来解决区间问题的很暴力的树形结构。

特色:珂朵莉树支持区间推平(将区间$L$~$R$全部赋值为同一个值$x$)

3、在学习之前你需要知道:set(若熟悉此STL请跳过)

set的本质是一棵平衡树。特性为插入到set中的元素会被自动排序并且不允许set中有相同的元素。

珂朵莉树中需要用到的函数:

set t; //定义一个名为t,类型为Node(结构体)的set

s.begin(); //返回指向第一个元素的迭代器(地址)

s.end(); //返回指向最后一个元素的迭代器

s.clear(); //清空s

s.insert(a); //将a插入到s

s.erase(l, r);//将迭代器l~r之间的元素全部删除

s.lower_bound(a); //二分查找a在s中的位置,返回一个迭代器。

set::iterator pos; //定义一个迭代器pos。

4、珂朵莉树可以解决什么问题?

当我们需要推平一段区间时,可以使用珂朵莉树。珂朵莉树高效的基础是数据随机生成。也就是说,这个数据结构很容易被构造数据卡掉。但是在珂朵莉树依然鲜为人知的现在又有谁会去构造数据去卡一个知名度并不高的算法呢?你都愿意学SPFA了不是吗

来看一道例题:

题目大意:

我有一个可爱的序列。你需要编写程序支持以下操作:

1 l r x :将[l,r]区间所有数加上x

2 l r x :将[l,r]区间所有数改成x

3 l r x :输出将[l,r] 区间从小到大排序后的第x个数是的多少

4 l r x y :输出[l,r] 区间每个数字的$x$次方的和模y的值

5、珂朵莉树的构造

其实珂朵莉树被称作“树”大概仅仅是因为使用了set吧。在学习珂朵莉树时,你大可以不把它作为一个树来理解。

珂朵莉树的每一个节点由一个三元组(l, r, val)组成,表示区间$[l,r]$之间的值全是x。

例子: 我有一个可爱的序列:

1 1 1 1 1 2 2 2 2 3 3 3 3

则在珂朵莉树上这个序列被表示为(1, 5, 1) (6, 9, 2) (10, 14, 3)三个节点。

建树实现:

struct node {

int l, r;//区间左端点与右端点。

mutable lint v;//mutable为“可变的”,使我们可以直接修改v的值

node(int L, int R = -1, lint V = 0) : l(L), r(R), v(V) {}

bool operator < (const node &o) const {

return l < o.l;

}

}; //定义一个结构体,重载

set s;//扔到set里

是不是非常的简单好懂鸭?

6、核心操作:区间分割

考虑刚刚那个可爱的序列:

1 1 1 1 1 2 2 2 2 3 3 3 3

现在我要强人锁男将2~13这个区间全部加上1。

前文提到,在珂朵莉树上这个序列被表示为(1, 5, 1) (6, 9, 2) (10, 14, 3)三个节点。也就是说我们根本没有办法直接对2~13这个区间加上1.

这个时候如果我们将(1, 5, 1) (6, 9, 2) (10, 14, 3)三个区间分割为(1, 1, 1) (2, 5, 1) (6, 9, 2) (9, 13, 3) (14, 14, 3)这几个区间就可以直接对区间2~13中所对应的节点直接进行操作啦!超快乐!

∴现在我们需要写一个函数spilit(pos),将pos所在的节点以pos为中心分为两个节点。

实现步骤:

找到pos所在的节点(l, r, val)

删掉这个节点

把这个节点变成(l, pos-1, val)和(pos, r, val)扔回set。

返回右区间迭代器(以后有用)

代码实现:

#define IT set::iterator

//迭代器宏定义

IT spilit (int pos) {

IT it = s.lower_bound(node(pos, -1, 0));//找到第一个l不小于pos的节点

if(it != s.end() && it->l == pos) return it;//不需要分割直接退出

it--;//pos一定在前一个区间中

int L = it -> l, R = it -> r;

lint V = it->v;

s.erase(it);//删了

s.insert(node(L, pos-1, V));//左区间丢进去

return s.insert(node(pos, R, V)).first;//右区间丢进去,返回右区间的迭代器。

}

是不是特别简单?

7、降低复杂度的关键:区间赋值(推平)

实现步骤: 设要推平的区间为[l, r]。

把l和r所在的节点分割。

把要推平的区间[l, r]之间的节点全部删掉。

把(l, r, val)扔进set

没了。诗乃觉得没有什么需要解释的了。

#define IT set::iterator

void tp(int l, int r, int val) {

IT il = spilit(l), ir = spilit(r+1);

s.erase(il, ir);

s.insert(node(l, r, val));

}

8、当我们要对一段区间进行操作时:

设要操作的区间为[l, r]。

我们先把l和r所在的节点分割,暴力对区间[l, r]中的节点一个个取出来操作(修改或统计答案)即可,反正没有多少节点。这个东西视具体题目而定,这里不再赘述。

例子:区间加

#define IT set::iterator

void add(int l, int r, int val) {

IT il = spilit(l), ir = spilit(r+1);

for(; il != ir; il->v += val, il++);

}

9、我最喜欢暴力数据结构了。

惊不惊喜?现在你已经学会珂朵莉树了,可以做一做例题练一下手呢。(是NOI+/CTSC难度的黑题哦)。

其他例题: CF915E 、bzoj4293(权限题)

珂朵莉树的优点:码量少,好理解,调错快。

缺点:在数据随机的时候推平操作比较多,所以它的复杂度会趋近于mlogn(m为询问次数)。但当出题人想要卡珂朵莉树时肯定会T飞。珂朵莉这么可爱谁会卡呢

10、我永远喜欢珂朵莉!

Comet OJ - Contest &num;14 转转的数据结构题 珂朵莉树&plus;树状数组

题目链接: 题意:有两个操作 操作1:给出n个操作,将区间为l到r的数字改为x 操作2:给出q个操作,输出进行了操作1中的第x到x+y-1操作后的结果 解法: 把询问离线,按照r从小到大排序 每次询问 ...

数据结构31:树&lpar;Tree&rpar;详解

复制广义表数据结构中的树 树是数据结构中比较重要也是比较难理解的一类存储结构.本章主要主要围绕二叉树,对树的存储以及遍历做详细的介绍,同时还会涉及到有关树的实际应用,例如构建哈弗曼编码等. 由于树存储 ...

Redis数据结构详解之List(二)

序言 思来想去感觉redis中的list没什么好写的,如果单写几个命令的操作过于乏味,所以本篇最后我会根据redis中list数据类型的特殊属性,同时对比成熟的消息队列产品rabbitmq,使用red ...

数据结构图文解析之:队列详解与C&plus;&plus;模板实现

0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

数据结构图文解析之:AVL树详解及C&plus;&plus;模板实现

0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

数据结构图文解析之:二叉堆详解及C&plus;&plus;模板实现

0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

数据结构图文解析之:哈夫曼树与哈夫曼编码详解及C&plus;&plus;模板实现

0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

redis 五种数据结构详解(string,list,set,zset,hash)

redis 五种数据结构详解(string,list,set,zset,hash) Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存 ...

&lbrack;一&rsqb;class 文件浅析 &period;class文件格式详解 字段方法属性常量池字段 class文件属性表 数据类型 数据结构

前言概述  本文旨在讲解class文件的整体结构信息,阅读本文后应该可以完整的了解class文件的格式以及各个部分的逻辑组成含义   class文件包含了java虚拟机指令集 和  符号表   以及若 ...

随机推荐

LINUX 编译安装 PHP 环境

今天终于有时间 总结一下 linux 的编译安装 php 环境同学给我发了他写的文档 ,基本就可以实现编译安装了我同学文章地址: http://penghui.link/articles/2016/0 ...

你不知道的HttpHandler相关知识

一.关于IHttpHandler.IsReusable 很多人不明白,这哥们到底干嘛的,估计是微软最初的一个想法--让一个对象可以一直不断地被重复使用 ,但这个想法不成熟,会带来很多隐藏问题,一个对象 ...

JS----------&gt&semi;数组练习&excl;

var arr = [4, 0, 7, 9, 0, 0, 2, 6, 0, 3, 1, 0]; 要求将数组中的0项去掉,将不为0的值存入一个新的数组,生成新的数组 ..

HDU 3085 Nightmare II 双向bfs 难度&colon;2

http://acm.hdu.edu.cn/showproblem.php?pid=3085 出的很好的双向bfs,卡时间,普通的bfs会超时 题意方面: 1. 可停留 2. ghost无视墙壁 3. ...

JavaScript 兼容处理IE67之 &excl;&quot&semi;a&quot&semi;&lbrack;0&rsqb;

IE67对字符串进行取值需要使用charAt()方法,不能直接通过数组方式的坐标访问:

python开发环境搭建及numpy基本属性-【老鱼学numpy】

目的 本节我们将介绍如何搭建python的开发环境以及numpy的基本属性,这样可以检验我们的numpy是否安装正确了. python开发环境的搭建 工欲善其事必先利其器,我用得比较顺手的是Intel ...

Zookeeper 集群安装配置,超详细,速度收藏!

今天,栈长分享下 Zookeeper 的集群安装及配置. 下载 下载地址:http://zookeeper.apache.org/ 下载过程就不说了,我们下载了最新的zookeeper-3.4.11. ...

EMM386和UMBPCI 区别

EMM386和UMBPCI 区别 1,SupportCD-ROM[HIMEM+EMM386NOEMS].支持光驱(EMM386模式)2,SupportCD-ROM[HIMEM+UMBPCI].支持光驱 ...

2、使用Angular-CLI初始化Angular项目(踩过的深坑!!!)

1.step1:建一个放项目的文件夹,打开cmd,或vs code的终端,找到文件夹根目录 2.step2:初始化脚手架 初始化命令: ng new 项目名称 --skip-install 注意:-- ...

PAT A1075 PAT Judge (25 分)——结构体初始化,排序

The ranklist of PAT is generated from the status list, which shows the scores of the submissions. Th ...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值