首页 > 其他分享 >珂朵莉树(ODT)学习笔记

珂朵莉树(ODT)学习笔记

时间:2024-10-07 14:44:40浏览次数:11  
标签:itl int auto ODT 笔记 朵莉树 split inline mp

对一个序列进行推平和查询等操作,我们难免会有过这样的想法:只维护连续段即可。但是这只是比较优的暴力,精心构造的数据可以轻松卡掉。
事实上,在随机数据下,这样的算法的时间复杂度是 \(\mathcal{O}(n\log n)\),这就是颜色段均摊理论,证明不会。
根据这个理论产生了珂朵莉树,它可以维护区间推平和查询操作。
具体来说,可以用一些数据结构来维护颜色端,在进行操作时找到相应的颜色段,修改后合并。
珂朵莉树的核心是分裂 split 和合并 assign 操作,大体有三种实现方法。
节点类型:

struct NODE{
	int l,r;mutable int v;
	inline bool operator<(const NODE&a)const{return l<a.l;}
}

std::set 中的元素是静态的,不可改变,而 mutable 可以强制突破 const 的限制,使操作更简洁。

std::set 实现

主流写法。

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

split 函数可以将包含 \(x\) 位置的区间分裂为两个区间,返回后一个区间的迭代器。

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

assign 函数可以将 \([l,r]\) 中的所有区间合并为一个,并区间推平。后 split(r+1) 可能会使 split(l) 失效,所以顺序不能变。

inline void perform(int l,int r){
	auto itr=split(r+1),itl=split(l);
	for(;itl!=itr;++itl){
		// Do Something here
	}
}

perform 函数可以遍历一遍 \([l,r]\) 中的区间,进行相关操作。

std::map 实现

观察上面的代码,发现 NODE 中的右端点并没有起作用,不妨使用 std::<int,int>map 只记录左端点和权值即可,操作更加简洁。

inline auto split(int x){
	auto it=std::prev(mp.lower_bound(x));
	return mp.insert(it,{x,it->second});
}
inline void assign(int l,int r,int v){
	split(l);split(r);auto it=mp.find(l);
	while(it->first!=r)it=mp.erase(it);
	mp[l]=v;
}

链表实现

不会链表

CF896C
CF915E

标签:itl,int,auto,ODT,笔记,朵莉树,split,inline,mp
From: https://www.cnblogs.com/Ishar-zdl/p/18449328

相关文章

  • 高性能计算学习笔记(1)
    一、程序优化CPU程序优化1.1体系结构:CPU流水线技术、高速缓指令集、CPU超标量设计1.2并行技术:MPI、OpenMP、SIMD、汇编1.3算法:算法优化GPU程序优化1.1GPU的体系结构(计算核心、高带宽、多级存储)1.2GPU并行框架:CUDA、OpenCL、OpenACC1.3并行设计的算法程序优化核心......
  • prometheus学习笔记之PromQL
    prometheus学习笔记之PromQL一、PromQL语句简介官方文档:https://prometheus.io/docs/prometheus/latest/querying/basics/Prometheus提供⼀个函数式的表达式语⾔PromQL(PrometheusQueryLanguage),可以使⽤户实时地查找和聚合时间序列数据,表达式计算结果可以在图表中展示,也可......
  • ABB_800xA学习笔记314:做一个实际的练习1
    国庆节懒了几天尽去玩了,没有学习。我把前段时间在新浪博客记录的内容转发在这里,那里把访问量清零后还没有恢复。原文地址:ABB_800xA学习笔记314:做一个实际的练习1_来自金沙江的小鱼_新浪博客(sina.com.cn)很久没有学习ABB800xA了,现场有一套800xA的设备,如果出了问题还是得区处理......
  • 【笔记】SSTI学习
    【笔记】SSTI学习原文章:尝试黑客攻击|SSTI(tryhackme.com)介绍服务器端模板注入(SSTI)是一种web漏洞攻击,它利用模板引擎的不安全特性实现。什么是模板引擎?模板引擎允许您创建可以在应用程序中重复使用的静态模板文件。这是什么意思?想象一个存储用户信息的页面。在Python......
  • Arduino物联网开发笔记01
    首先将开发板连接电脑然后下载Arduinoide(我的是2.0版的)这是官网的下载链接:https://www.arduino.cc/en/software接着左上角项目新建文件夹编写第一个程序`voidsetup(){Serial.begin(115200);//设置串口波特率}voidloop(){Serial.printf("Helloworld\n");delay(500)......
  • 高精度加法笔记
    vector<int>u;//储存a倒序的每个数vector<int>v;//储存b倒序的每个数vector<int>add(vector<int>m,vector<int>n){//高精度加法 vector<int>temp;//temp数组存储相加后的每个数 intt=0;//t作为每个数相加的和 for(inti=0;i<m.size()||i<n.size();......
  • 折腾笔记[2]-跨平台打包tauri程序
    摘要在macOS(arm64)平台打包tauri程序到Windows(amd64)平台.AbstractPackagingaTauriapplicationfortheWindows(amd64)platformfrommacOS(arm64).关键信息构建平台:macOS14.6.1(arm64)目标平台:Window10(amd64)原理简介nsis简介[https://nsis.sourceforg......
  • 珂朵莉树(ODT)
    前言主要是一种暴力思想。。。本文来自wiki与洛谷题解的整合。应用主要是应付随机数据(区间操作)实现有几个核心操作。set实现方法定义structnode{ inttl,r;//intt:longlong mutableinttv; node(constintt&ll,constintt&rr,constintt&vv):l(ll),r(rr),v......
  • 归并排序笔记
    inttmp[];//temp数组存储数据voidmerge_sort(inta[],intl,intr){ if(l>=r)return;//递归到最后只有一个数返回 intmid=(l+r)/2;//确定分界点l~midmid+1~r; merge_sort(a,l,mid); merge_sort(a,mid+1,r);//递归左右两边 intk=0,i=l,j=mi......
  • Living-Dream 系列笔记 第80期(国庆集训合集)
    IDDFS使用场景:搜索树非常大而答案的深度较浅,一般在\(20\)以内,且dfs会TLE,bfs会MLE。算法原理:以dfs的形式搜索;设定搜索的深度限制\(dep\);dfs深度不能超过\(dep\),且要恰好遍历所有\(dep\)的状态;若在\(dep\)层没有找到答案,\(dep+1\todep\),重新DFS......