ODT 学习笔记「建议收藏」

ODT 学习笔记「建议收藏」珂朵莉,要一直幸福下去哟!warning:本文在大白天书写,脑子可能不大好用。目前代码选自题解,等有时间自己写一下。简介ODT(OldDriverTree(中文译名张舟树),又称ChthollyTree,即众人皆知的珂朵莉树)是一种非常暴力的思想或者做法(注意我没有说是数据结构)简单来说,其核心思想是把一段区间推平(这也是其适用的地方——区间赋值),推平之后,原数列变成一段一段的了(每段的数值相同),然后就可以搞事了。ODT在随机数据下,复杂度近似O(mlogn)O(mlog

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

珂朵莉,要一直幸福下去哟!

warning:本文在大白天书写,脑子可能不大好用。

目前代码选自题解,等有时间自己写一下。

简介

ODT(Old Driver Tree(中文译名张舟树),又称 Chtholly Tree,即众人皆知的珂朵莉树) 是一种非常暴力的思想或者做法 (注意我没有说是数据结构)

简单来说,其核心思想是把一段区间推平(这也是其适用的地方——区间赋值),推平之后,原数列变成一段一段的了(每段的数值相同),然后就可以搞事了。

ODT 在随机数据下,复杂度近似 O ( m l o g n ) O(m log n) O(mlogn),证明请自行翻参考资料。

前置知识

熟练使用 STL(至少要熟练使用 set)或者会写平衡树。

初始化

我们维护一个结构体 n o d e node node,包含 l , r , d l,r,d l,r,d d d d 是题目要求维护的值),表示一个被推平的区间。

struct node{ 
   
	ll l,r;
	mutable ll v;
	node(ll l,ll r=0,ll v=0):l(l),r(r),v(v){ 
   };
	inline operator <(const node &a)const{ 
   
		return l<a.l;
	}
};

有意思的一个结论:只要没有线段被另一条线段完全覆盖,那么按左端点排序后右端点同样有序。

mutable 可以看成 const 的反义词,被 mutable 修饰的变量不受 const 的影响,一直变化。

注:下文的“复杂度”均指在随机数据下

split 操作

ODT 两大核心操作之一,用处是当出现某些修改操作后,我们推平的区间将被分裂(一个区间中必须值相同),这个时候这个区间就会被分裂成两个。也就是 [ l , p o s − 1 ] [l,pos-1] [l,pos1] [ p o s , r ] [pos,r] [pos,r]

#define IT set<node>::iterator
IT split(int pos){ 
   
	IT it=s.lower_bound(node(pos));//求前驱
	if(it!=s.end()&&it->l==pos)return it;//如果it的l值就是左端点,换句话说pos的位置恰好是l,就不需要分裂了
	it--;//见上
	int L=it->l,R=it->r;ll V=it->v;
    	s.erase(it);//彻底抹掉
   	s.insert(node(L,pos-1,V));//先建[l,pos-1]
	return s.insert(node(pos,R,V)).first;//然后建[pos,r],同时返回后半段区间的迭代器
}

复杂度为 O ( l o g n ) O(log n) O(logn)

assign 操作

ODT 两大核心操作之二,也就是推平一个区间,说起来比较高大上,其实就是区间赋值。

void assign(int l,int r,int val=0){ 
   
	IT itr=split(r+1),itl=split(l);//注意一定要先split r+1
	s.erase(itl,itr);
   	s.insert(node(l,r,val));//先删除小区间,直接覆盖为大区间 
}

其他操作

ODT 有点技术含量的操作就这俩,剩余都是暴力(字面意思),下面以 梦 开 始 的 地 方 (目前看来也是梦结束的地方)——CF896C为例介绍一下。

首先是所有操作的套路,先 split 一下右端点,再 split 一下左端点,得到两个端点的迭代器,然后直接暴力求解。

比如区间加:

void add(int l, int r, LL k=1)
{ 
   
	IT itl=split(l),itr=split(r+1);
	for(;itl!=itr;++itl) 
        itl->v+=k;
}

当我第一次看到这个操作时我的内心想法:

珂朵莉树区间加很暴力是怎么回事呢?珂朵莉树相信大家都很熟悉,但是珂朵莉树区间加很暴力是怎么回事呢,下面就让小编带大家一起了解吧。
  珂朵莉树区间加很暴力,其实就是珂朵莉树就是暴力,大家可能会很惊讶珂朵莉树怎么会区间加很暴力呢?但事实就是这样,小编也感到非常惊讶。
  这就是关于珂朵莉树区间加很暴力的事情了,大家有什么想法呢,欢迎在评论区告诉小编一起讨论哦!

再比如说区间幂次,这个有意思,主流数据结构(*队,线*树,**树)都做不到一个优秀的复杂度(小声:在随机数据下)

ll sum(int l,int r,int ex,int mod){ 
   
	IT itl=split(l),itr=split(r+1);
	LL res=0;
	for (;itl!=itr;++itl)
		res=(res+(LL)(itl->r-itl->l+1)*pow(itl->v,LL(ex),LL(mod)))%mod;
	return res;
}

就还是暴力呗。

ODT 有什么特点?容易被卡好写!所以我们在最后介绍这个比较长的操作:区间 k k k 小。

ll rank(int l,int r,int k){ 
   
	vector<pair<ll,int> >t;
    t.clear();
	IT itl=split(l),itr=split(r+1);
	for(;itl!=itr;++itl)
    t.push_back(pair<ll,int>(itl->v,itl->r-itl->l+1));
	sort(t.begin(),t.end());
	for(vector<pair<ll,int> >::iterator it=t.begin();it!=t.end();++it){ 
   
		k-=it->second;
		if(k<=0)
        return it->first;
	}
	return -1ll;
}

总结

这是一种极其适合骗分的暴力算法,好写,好调。

ODT 就是对暴力的优化,其核心是区间覆盖这个操作,正是区间覆盖让 ODT 焕发生机。

区间覆盖,发生了会如何,不发生又会如何。 在这种困难的抉择下,本人思来想去,寝食难安。 马克思说过一句著名的话,一切节省,归根到底都归结为时间的节省。这句话语虽然很短, 但令我浮想联翩. 既然如此, 可是,即使是这样,区间覆盖的出现仍然代表了一定的意义。 生活中,若区间覆盖出现了,我们就不得不考虑它出现了的事实。 问题的关键究竟为何? 区间覆盖,发生了会如何,不发生又会如何。 在这种困难的抉择下,本人思来想去,寝食难安。 迈克尔·F·斯特利说过一句著名的话,最具挑战性的挑战莫过于提升自我。我希望诸位也能好好地体会这句话. 区间覆盖,到底应该如何实现。 每个人都不得不面对这些问题。 在面对这种问题时, 吕凯特说过一句富有哲理的话,生命不可能有两次,但许多人连一次也不善于度过。这启发了我. 亚伯拉罕·林肯说过一句著名的话,我这个人走得很慢,但是我从不后退。这句话看似简单,但其中的阴郁不禁让人深思. 生活中,若区间覆盖出现了,我们就不得不考虑它出现了的事实。 要想清楚,区间覆盖,到底是一种怎么样的存在。 区间覆盖,发生了会如何,不发生又会如何。 可是,即使是这样,区间覆盖的出现仍然代表了一定的意义。 我们一般认为,抓住了问题的关键,其他一切则会迎刃而解。 区间覆盖的发生,到底需要如何做到,不区间覆盖的发生,又会如何产生。 区间覆盖,到底应该如何实现。 我们都知道,只要有意义,那么就必须慎重考虑。 生活中,若区间覆盖出现了,我们就不得不考虑它出现了的事实。 问题的关键究竟为何? 文森特·皮尔在不经意间这样说过,改变你的想法,你就改变了自己的世界。这句话看似简单,但其中的阴郁不禁让人深思. 对我个人而言,区间覆盖不仅仅是一个重大的事件,还可能会改变我的人生。 一般来说, 区间覆盖的发生,到底需要如何做到,不区间覆盖的发生,又会如何产生。 我们都知道,只要有意义,那么就必须慎重考虑。 区间覆盖,发生了会如何,不发生又会如何。 带着这些问题,我们来审视一下区间覆盖。
  这种事实对本人来说意义重大,相信对这个世界也是有一定意义的。 经过上述讨论, 那么, 杰纳勒尔·乔治·S·巴顿说过一句著名的话,接受挑战,就可以享受胜利的喜悦。这句话把我们带到了一个新的维度去思考这个问题: 我认为, 了解清楚区间覆盖到底是一种怎么样的存在,是解决一切问题的关键。 现在,解决区间覆盖的问题,是非常非常重要的。 所以, 经过上述讨论, 生活中,若区间覆盖出现了,我们就不得不考虑它出现了的事实。 区间覆盖,发生了会如何,不发生又会如何。 老子在不经意间这样说过,知人者智,自知者明。胜人者有力,自胜者强。这似乎解答了我的疑惑. 生活中,若区间覆盖出现了,我们就不得不考虑它出现了的事实。 既然如何, 一般来讲,我们都必须务必慎重的考虑考虑。 区间覆盖,到底应该如何实现。 从这个角度来看, 而这些并不是完全重要,更加重要的问题是, 可是,即使是这样,区间覆盖的出现仍然代表了一定的意义。 问题的关键究竟为何? 富兰克林在不经意间这样说过,你热爱生命吗?那么别浪费时间,因为时间是组成生命的材料。带着这句话, 我们还要更加慎重的审视这个问题。
  这样看来, 那么, 从这个角度来看, 那么, 问题的关键究竟为何? 生活中,若区间覆盖出现了,我们就不得不考虑它出现了的事实。 就我个人来说,区间覆盖对我的意义,不能不说非常重大。
  那么, 本人也是经过了深思熟虑,在每个日日夜夜思考这个问题。 对我个人而言,区间覆盖不仅仅是一个重大的事件,还可能会改变我的人生。 郭沫若说过一句富有哲理的话,形成天才的决定因素应该是勤奋。这不禁令我深思. 区间覆盖的发生,到底需要如何做到,不区间覆盖的发生,又会如何产生。 既然如此, 带着这些问题,我们来审视一下区间覆盖。 每个人都不得不面对这些问题。 在面对这种问题时。
  莎士比亚曾经提到过,本来无望的事,大胆尝试,往往能成功。我希望诸位也能好好地体会这句话. 这样看来, 生活中,若区间覆盖出现了,我们就不得不考虑它出现了的事实。 区间覆盖因何而发生? 问题的关键究竟为何? 区间覆盖,发生了会如何,不发生又会如何。 左拉在不经意间这样说过,生活的道路一旦选定,就要勇敢地走到底,决不回头。这似乎解答了我的疑惑. 了解清楚区间覆盖到底是一种怎么样的存在,是解决一切问题的关键。 一般来说。
  在这种困难的抉择下,本人思来想去,寝食难安。 一般来讲,我们都必须务必慎重的考虑考虑。 总结的来说, 区间覆盖因何而发生? 歌德说过一句著名的话,没有人事先了解自己到底有多大的力量,直到他试过以后才知道。带着这句话, 我们还要更加慎重的审视这个问题: 既然如此, 马克思说过一句著名的话,一切节省,归根到底都归结为时间的节省。这启发了我. 迈克尔·F·斯特利曾经提到过,最具挑战性的挑战莫过于提升自我。带着这句话, 我们还要更加慎重的审视这个问题。

参考资料:

CF896C 的题解

珂朵莉树 OI wiki

珂朵莉树的复杂度分析 知乎

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/197643.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • JAVA和C++区别

    JAVA和C++区别 JAVA和C++都是面向对象语言。也就是说,它们都能够实现面向对象思想(封装,继乘,多态)。而由于c++为了照顾大量的C语言使用者,而兼容了C,使得自身仅仅成为了带类的C语言,多多少少影响了其面向对象的彻底性!JAVA则是完全的面向对象语言,它句法更清晰,规模更小,更易学。它是在对多种程序设计语言进行了深入细致研究的基础上,据弃了其他语言的不足之处,从根本上解决了c++的固有缺陷。Java和

    2022年7月7日
    16
  • Oracle 创建表空间和用户「建议收藏」

    Oracle 创建表空间和用户「建议收藏」文章目录一、创建表空间二、创建用户一、创建表空间表空间?ORACLE数据库的逻辑单元。数据库—表空间:一个表空间可以与多个数据文件(物理结构)关联一个数据库下可以建立多个表空间,一个表空间可以建立多个用户、一个用户下可以建立多个表。创建表空间必须使用具有超级管理员权限的用户,这里就是system下面的Connetas表示连接数据库的身份,一般选择Normal,表示一般的身份,下面两个表示修改数据库的配置,一般是管理员的操作功能选择。(1)打开创建数据库的窗口(2)创建表

    2022年7月27日
    1
  • Navicat Premium 15激活码【2021.10最新】

    (Navicat Premium 15激活码)最近有小伙伴私信我,问我这边有没有免费的intellijIdea的激活码,然后我将全栈君台教程分享给他了。激活成功之后他一直表示感谢,哈哈~https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~09LV…

    2022年3月28日
    59
  • NR信道带宽利用率、NR-ARFCN与channel raster[通俗易懂]

    NR信道带宽利用率、NR-ARFCN与channel raster[通俗易懂]1.NR的信道带宽利用率  相比4G最高仅90%的信道带宽利用率,5GNR进一步提高信道带宽利用率,最高可达98.28%,需要各厂家自主实现对OOB的抑制,可采用filter、windowing技术等。  2.NR-ARFCN与channelraster…

    2022年10月9日
    1
  • pycharm创建flask项目没有子文件夹和app文件_python flask框架

    pycharm创建flask项目没有子文件夹和app文件_python flask框架打开Pycharm的File菜单,选择创建新的项目,在弹出对话框中,我们可以看到很多的案例,Flask、Django等等,我们选择Flask创建Flask项目。选择创建之后一个Flask项目就出现在我们眼前:默认文件目录结构为:app.py程序入口,static用于存放静态文件,如js、css、img等,templates用于放置html模板文件在Pycharm菜单栏有个run,我们可以选择run来启动Flask服务,默认打开的是5000端口打开浏览器输入http://lo.

    2022年8月29日
    2
  • visio 2013密钥「建议收藏」

    2NYF6-QG2CY-9F8XC-GWMBW-29VV8FJ2N7-W8TXC-JB8KB-DCQ7Q-7T7V3VXX6C-DN3HQ-3CRXG-RF4KT-YG7V3B3C7Q-D6NH2-2VRFW-HHWDG-FVQB666DNF-28W69-W4PPV-W3VYT-TJDBQN4M7D-PD46X-TJ2HQ-RPDD7-T28P9ND3G9-KQHY4-8P3W2-VG…

    2022年4月16日
    119

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号