珂朵莉树(Chtholly Tree)学习笔记
珂朵莉树(Chtholly Tree)学习笔记
珂朵莉树原理
其原理在于运用一颗树(set,treap,splay......)其中要求所有元素有序,并且支持基本的操作(删除,添加,查找......)来实现区间压缩。
那么区间压缩的意义在于区间推平这是珂朵莉树的核心(如果没有这个操作实际上不一定需要这种算法)
ps:若保证有连续相等甚至递增的区间,也可以的(吧?)。
可想而知它的操作在于对区间的分裂和合并操作
(为什么?因为这样可以方便而快捷的区间推平)
珂朵莉树的实现
在众多树中因为set这个c++自带,所以决定选择它。
结构
一个node结构体——把它叫区间(已typedef long long LL)
struct node
{
int l,r;LL v;//这里官方写法加了一个mutable,看个人写法
node(int L,int R,LL V):l(L),r(R),v(V){}
bool operator < (const node& o) const
{
return l<o.l;
}
};
声明集合
set<node>s;
初始化
for(int i=1;i<=n;++i)
s.insert(i,i,val);
s.insert(n+1,n+1,0);//见下面中it!=s.end()的前提
分裂
#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;
int ll=it->l,rr=it->r;
LL vv=it->v;
s.erase(it);
s.insert(node(ll,pos-1,vv));
return s.insert(node(pos,rr,vv)).first;
}
区间推平
void assign(int l,int r,LL val=0)
{
it_ itl=split(l),itr=split(r+1);
s.erase(itl,itr);
s.insert(node(l,r,val));
}
如上。
栗例子
见cf896c
仅仅给出代码
#include <bits/stdc++.h>
#define it_ set<node>::iterator
// #define swap(X,Y) {int (tmp)=(X),(X)=(Y),(Y)=(tmp);}
using namespace std;
typedef long long LL;
const int M7=1e9+7;
const int maxn=1e5+5;
int n,m;
LL seed,vmax;
LL a[maxn];
struct node
{
int l,r;mutable LL v;
node(int L,int R=-1,LL V=0):l(L),r(R),v(V){}
bool operator < (const node& o) const
{
return l<o.l;
}
};
set<node>s;
it_ split(int pos)
{
it_ it=s.lower_bound(node(pos));
if(it!=s.end()&& it->l==pos) return it;
--it;
int ll=it->l,rr=it->r;
LL vv=it->v;
s.erase(it);
s.insert(node(ll,pos-1,vv));
return s.insert(node(pos,rr,vv)).first;
}
void assign(int l,int r,LL val=0)
{
it_ itl=split(l),itr=split(r+1);
s.erase(itl,itr);
s.insert(node(l,r,val));
}
void add(int l,int r,LL val=0)
{
it_ itl=split(l),itr=split(r+1);
for(it_ i=itl;i!=itr;++i)
{
i->v+=val;
}
}
LL so(int l,int r,int k)
{
it_ itl=split(l),itr=split(r+1);
vector<pair<LL,int>>v;
v.clear();
for(;itl!=itr;++itl)
{
v.push_back(pair<LL,int>(itl->v,itl->r-itl->l+1));
}
sort(v.begin(),v.end());
for(vector<pair<LL,int>>::iterator it=v.begin();it!=v.end();++it)
{
k-=it->second;
if(k<=0)return it->first;
}
}
LL pow(LL a,LL b,LL mod)
{
LL ret=1;a%=mod;
while(b)
{
if(b&1) ret=ret*a%mod;
a=a*a%mod;
b>>=1;
}
return ret%mod;
}
LL ok(int l,int r,LL k,LL mod)
{
it_ itl=split(l),itr=split(r+1);
LL ans=0;
for(;itl!=itr;++itl)
{
ans+=(LL)(itl->r-itl->l+1)*pow(itl->v,k,mod)%mod;
ans%=mod;
}
return ans%mod;
}
LL rnd()
{
LL ret=seed;
seed=(seed*7+13)%M7;
return ret;
}
int main(int argc, char const *argv[])
{
ios::sync_with_stdio(0);
cin>>n>>m>>seed>>vmax;
for(int i=1;i<=n;++i)
{
a[i]=(rnd()%vmax)+1;
s.insert(node(i,i,a[i]));
}
s.insert(node(n+1,n+1,0));
for(int i=1;i<=m;++i)
{
int op=(rnd()%4)+1,
l=(rnd()%n)+1,
r=(rnd()%n)+1;LL x,y;
if(l>r)
swap(l,r);
if(op==3)
x=(rnd()%(LL)(r-l+1))+1;
else
x=(rnd()%vmax)+1;
if(op==4)
y=(rnd()%vmax)+1;
if(op==1) add(l,r,x);
else if(op==2) assign(l,r,x);
else if(op==3) cout<<so(l,r,x)<<endl;
else if(op==4) cout<<ok(l,r,x,y)<<endl;
}
return 0;
}
珂朵莉树(Chtholly Tree)学习笔记的更多相关文章
- 「学习笔记」珂朵莉树 ODT
珂朵莉树,也叫ODT(Old Driver Tree 老司机树) 从前有一天,珂朵莉出现了... 然后有一天,珂朵莉树出现了... 看看图片的地址 Codeforces可还行) 没错,珂朵莉树来自Co ...
- 『珂朵莉树 Old Driver Tree』
珂朵莉树 珂朵莉树其实不是树,只是一个借助平衡树实现的数据结构,主要是对于有区间赋值的数据结构题,可以用很暴力的代码很高效地完成任务,当然这是建立在数据随机的基础上的. 即使数据不是随机的,写一个珂朵 ...
- 珂朵莉树(ODT)笔记
珂朵莉树,又叫老司机树($Old\, Driver \, Tree$) 是一种暴力出奇迹,就怕数据不随机的数据结构. 适用 需要用线段树维护一些区间修改的信息…… 像是区间赋值(主要),区间加…… 原 ...
- CF896C Willem, Chtholly and Seniorious(珂朵莉树)
中文题面 珂朵莉树的板子……这篇文章很不错 据说还有奈芙莲树和瑟尼欧里斯树…… 等联赛考完去学一下(逃 //minamoto #include<bits/stdc++.h> #define ...
- [转]我的数据结构不可能这么可爱!——珂朵莉树(ODT)详解
参考资料: Chtholly Tree (珂朵莉树) (应某毒瘤要求,删除链接,需要者自行去Bilibili搜索) 毒瘤数据结构之珂朵莉树 在全是珂学家的珂谷,你却不知道珂朵莉树?来跟诗乃一起学习珂朵 ...
- 洛谷$P2572\ [SCOI2010]$ 序列操作 线段树/珂朵莉树
正解:线段树/珂朵莉树 解题报告: 传送门$w$ 本来是想写线段树的,,,然后神仙$tt$跟我港可以用珂朵莉所以决定顺便学下珂朵莉趴$QwQ$ 还是先写线段树做法$QwQ$? 操作一二三四都很$eas ...
- 题解 P3372 【【模板】线段树 1】(珂朵莉树解法)
这道题可以用珂朵莉树做,但是由于数据比较不随机,而我也没有手写一颗平衡树,所以就被卡掉了,只拿了70分. 珂朵莉树是一种基于平衡树的(伪)高效数据结构. 它的核心操作是推平一段区间. 简而言之,就是把 ...
- 洛谷AT2342 Train Service Planning(思维,动态规划,珂朵莉树)
洛谷题目传送门 神仙思维题还是要写点东西才好. 建立数学模型 这种很抽象的东西没有式子描述一下显然是下不了手的. 因为任何位置都以\(k\)为周期,所以我们只用关心一个周期,也就是以下数都在膜\(k\ ...
- 洛谷P4344 [SHOI2015]脑洞治疗仪(珂朵莉树)
传送门 看到区间推倒……推平就想到珂朵莉树 挖脑洞直接assign,填坑先数一遍再assign再暴力填,数数的话暴力数 //minamoto #include<iostream> #inc ...
随机推荐
- 2-6 Opencv模块组织结构
https://opencv.org/releases.html https://sourceforge.net/projects/opencvlibrary/files/opencv-win/3.4 ...
- C++中class在实例化前到底占用多少空间
最近忽然想起一个问题,C++中class在实例化前到底占用多少空间?我隐约记得书上是这么说的“类在实例化时才分配空间”!但是当我写下这个小程序的时候,杯具产生了—— #include<iostr ...
- jQuery入坑指南
前言 Ajax官方文档 爱jQuery jQuery插件库 jQuery中文api input 赋值和取值 记录一下: 在写一个input赋值,二话不说就直接利用了$('#xx').val()来进行取 ...
- 算法复习周------“动态规划之‘最长公共子序列’”&&《计蒜课》---最长公共子串题解
问题描述: 这个问题其实很容易理解.就是给你两个序列X={x1,x2,x3......xm} Y={y1,y2,y3......ym},要求找出X和Y的一个最长的公共子序列. 例:Xi={A, B, ...
- python 面向对象七 property() 函数和@property 装饰符
一.property引入 为了使对象的属性不暴露给调用者和进行属性值检查,设置了访问属性的接口函数,使用函数访问属性,并可以在函数内部检查属性. >>> class Student( ...
- bzoj 3456: 城市规划【NTT+多项式求逆】
参考:http://blog.miskcoo.com/2015/05/bzoj-3456 首先推出递推式(上面的blog讲的挺清楚的),大概过程是正难则反,设g为n个点的简单(无重边无自环)无向图数目 ...
- P5089 [eJOI2018]元素周期表(并查集)
传送门 以后看到棋盘要么黑白染色要么二分图! 我们考虑对行列建二分图,如果\(i\)行\(j\)列有,就把\(i\)和\(j+n\)连起来 我们要让它变成一张完全二分图.考虑条件\((i_1,j_1+ ...
- Luogu P1195/P1892 口袋的天空/BOI团伙 【最小生成树/并查集】By cellur925
其实这俩题挺水的,团伙拿下了一血,但是感觉还是写一下博客比较好x. 一.团伙 题目描述 1920年的芝加哥,出现了一群强盗.如果两个强盗遇上了,那么他们要么是朋友,要么是敌人.而且有一点是肯定的,就是 ...
- Springboot整合elasticsearch以及接口开发
Springboot整合elasticsearch以及接口开发 搭建elasticsearch集群 搭建过程略(我这里用的是elasticsearch5.5.2版本) 写入测试数据 新建索引book( ...
- [ZOJ1961]Let it Bead
Description "Let it Bead" company is located upstairs at 700 Cannery Row in Monterey, CA. ...