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

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

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • bug生命周期的状态

    bug生命周期的状态从一个bug被发现到这个bug被关闭这一段时间,bug可能会有以下状态:new,openPostpone,PendingRetest,Retest,PendingReject,Reject,Deferred,closed.(请注意这里有很多种状态,我们需要根据不同情况来决定怎样或者是否需要跟开发人员沟通)  下面就对这几种状态进行以下解释:  New:(新的)  当

  • 纳兰诗词

    纳兰诗词“空负凌云万丈志,一生襟抱未曾开”,情雅成诗,爱淡成词,如果没有潋滟坦白的心思,是无法走进古人留在书册中的幻境的。凡心所向,皆是虚妄。——一个人吃饭,旅行,到处走走停停;也一个人看书,弹琴,自己对话谈心。自我收敛,内心沉静,是我希望获得的心境,对纳兰容若不熟的人,恐怕会比较熟悉另外一个名字,纳兰明珠。如果我再说一句《七剑下天山》,恐十白你已经在点头微笑了:你说的是这个人。纳兰容若诞于清顺治

  • 常见免费邮箱 SMTP 服务地址及端口「建议收藏」

    常见免费邮箱 SMTP 服务地址及端口「建议收藏」常见免费邮箱SMTP服务地址及端口邮箱服务服务器地址SSL端口号非SSL端口号163邮箱IMAPimap.163.com993143SMTPsmtp.163.com465/99425POP3pop.163.com995110QQ邮箱IMAPimap.qq.com993143SMTPsmtp.qq.com465/58725POP3pop.qq.com995–foxmail邮箱IMAPimap

  • 十进制与八进制和十六进制之间的转换

    十进制与八进制和十六进制之间的转换

  • css动画和js动画的优缺点_彼得兔第三季动画片

    css动画和js动画的优缺点_彼得兔第三季动画片大家好,我是小丞同学,一名准大二的前端爱好者这篇文章将欢快的带你了解一下CSS和JS动画的差别愿你忠于自己,热爱生活引言讲到动画,当然是非常有意思的啦,你可以往上滑一下,看看上面的封面图,是不是相当的炫酷,以为我是代码写出来的吗?那当然不可能啊,我这么摸鱼,怎么会为了个封面图上号呢废话不多说,其实上面的动图用代码实现也不会很困难,这个图是用canva做出来的。本文主要讲以下这些内容浏览器渲染流程回流和重绘CSS动画JS动画两者对比

    2022年10月15日
  • Visio2013密钥_excel2013密钥

    Visio2013密钥_excel2013密钥C2FG9-N6J68-H8BTJ-BW3QX-RM3B3 2NYF6-QG2CY-9F8XC-GWMBW-29VV8 FJ2N7-W8TXC-JB8KB-DCQ7Q-7T7V3&

发表回复

您的电子邮箱地址不会被公开。

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