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)


相关推荐

  • jquery与vue区别_学jquery还是vue

    jquery与vue区别_学jquery还是vue仅仅从自己使用经验来说下感受。1,vue是一个前端框架,jquery是javacript库,封装了一些js常用的方法,仅此而已。vue有成熟的生态链,mvvm模式,是一个真正的web框架。表现在:1:vue有固定的写法和规定,必须要有一个div来作为容器,绑定事件方法,数据都有固定的地方,数据要写在data里面,方法要写在methods里面。而且绑定事件在dom元素标签上绑定,防止时间太…

  • 国外php网站_网盘资源搜索神器

    国外php网站_网盘资源搜索神器依赖管理依赖和包管理库Composer/Packagist:一个包和依赖管理器ComposerInstallers:一个多框架Composer库安装器Pickle:一个PHP扩展安装器 其他的依赖管理其他的相关依赖管理Satis:一个静态Composer存储库生成器Composition:一个在运行时检查Composer环境的库Version:语义版本的解析和比较

  • 安装Sql Server 2008R2报错0x84B10001[通俗易懂]

    安装Sql Server 2008R2报错0x84B10001[通俗易懂]解决方案:1、使用NotepadXML编辑C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\machine.config2、删除system.serviceModel这个区(Section)。3、保存修改。如果出现提示:对路径“C:\Windows\Microsoft.NET\Framework\v2.0.50727…

  • centos8.2内核版本_centos发行版本和内核版本

    centos8.2内核版本_centos发行版本和内核版本文章目录1.查看当前内核版本2.使用ELRepo仓库3.安装最新版内核4.设置以新的内核启动5.生成grub配置文件并重启系统6.验证新内核7.查看系统中已安装的内核8.删除旧内核9.参考文献1.查看当前内核版本使用的系统版本,当前日期CentOS最新版:1$cat/etc/redhat-release2CentOSLinuxrelease8.2.2004(Co…

  • JavaWeb项目org.apache.jasper.JasperException: 解决方法

    descriptionTheserverencounteredaninternalerror()thatpreventeditfromfulfillingthisrequest.exceptionorg.apache.jasper.JasperException:/PCManage/controlsecletthenews.jsp(303,12)ThefunctiongetNidmustbeusedwithaprefixwhenadefaultname

  • 重写和重载的区别是什么「建议收藏」

    重写和重载的区别是什么「建议收藏」重写和重载的区别是什么

发表回复

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

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