珂朵莉树(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)学习笔记的更多相关文章

  1. 「学习笔记」珂朵莉树 ODT

    珂朵莉树,也叫ODT(Old Driver Tree 老司机树) 从前有一天,珂朵莉出现了... 然后有一天,珂朵莉树出现了... 看看图片的地址 Codeforces可还行) 没错,珂朵莉树来自Co ...

  2. 『珂朵莉树 Old Driver Tree』

    珂朵莉树 珂朵莉树其实不是树,只是一个借助平衡树实现的数据结构,主要是对于有区间赋值的数据结构题,可以用很暴力的代码很高效地完成任务,当然这是建立在数据随机的基础上的. 即使数据不是随机的,写一个珂朵 ...

  3. 珂朵莉树(ODT)笔记

    珂朵莉树,又叫老司机树($Old\, Driver \, Tree$) 是一种暴力出奇迹,就怕数据不随机的数据结构. 适用 需要用线段树维护一些区间修改的信息…… 像是区间赋值(主要),区间加…… 原 ...

  4. CF896C Willem, Chtholly and Seniorious(珂朵莉树)

    中文题面 珂朵莉树的板子……这篇文章很不错 据说还有奈芙莲树和瑟尼欧里斯树…… 等联赛考完去学一下(逃 //minamoto #include<bits/stdc++.h> #define ...

  5. [转]我的数据结构不可能这么可爱!——珂朵莉树(ODT)详解

    参考资料: Chtholly Tree (珂朵莉树) (应某毒瘤要求,删除链接,需要者自行去Bilibili搜索) 毒瘤数据结构之珂朵莉树 在全是珂学家的珂谷,你却不知道珂朵莉树?来跟诗乃一起学习珂朵 ...

  6. 洛谷$P2572\ [SCOI2010]$ 序列操作 线段树/珂朵莉树

    正解:线段树/珂朵莉树 解题报告: 传送门$w$ 本来是想写线段树的,,,然后神仙$tt$跟我港可以用珂朵莉所以决定顺便学下珂朵莉趴$QwQ$ 还是先写线段树做法$QwQ$? 操作一二三四都很$eas ...

  7. 题解 P3372 【【模板】线段树 1】(珂朵莉树解法)

    这道题可以用珂朵莉树做,但是由于数据比较不随机,而我也没有手写一颗平衡树,所以就被卡掉了,只拿了70分. 珂朵莉树是一种基于平衡树的(伪)高效数据结构. 它的核心操作是推平一段区间. 简而言之,就是把 ...

  8. 洛谷AT2342 Train Service Planning(思维,动态规划,珂朵莉树)

    洛谷题目传送门 神仙思维题还是要写点东西才好. 建立数学模型 这种很抽象的东西没有式子描述一下显然是下不了手的. 因为任何位置都以\(k\)为周期,所以我们只用关心一个周期,也就是以下数都在膜\(k\ ...

  9. 洛谷P4344 [SHOI2015]脑洞治疗仪(珂朵莉树)

    传送门 看到区间推倒……推平就想到珂朵莉树 挖脑洞直接assign,填坑先数一遍再assign再暴力填,数数的话暴力数 //minamoto #include<iostream> #inc ...

随机推荐

  1. form的一个特性

    在一个form表单中,若只有一个input,按回车键表单会自动提交,但是当表单中存在多个input时,按回车键不会执行任何操作,这是form表单的一个特性

  2. wamp的手动安装

    Wamp的手动安装 (http://www.cnblogs.com/homezzm/archive/2012/08/01/2618062.html) 一.Apache2.4安装 1.修改\Apache ...

  3. WinXP下如何安装及御载MySQL服务

    一.安装及御载MySQL服务点击开始->运行,输入services.msc启动服务功能,如果发现以前安装过mysql,但是突然发现MySQL服务不见了,此时可以手动安装MySQL服务. 进入my ...

  4. java jdbc 与mysql连接的基本步骤

    Java与mysql链接的基本步骤: 第一步:注册驱动 方法一: DriverManager.registerDriver(new com.mysql.jdbc.Driver()); 方法二:设置属性 ...

  5. bzoj 2660: [Beijing wc2012]最多的方案【dp】

    有点神奇的dp 首先注意到任意一个数都能被表示成若干个斐波那契数的和的形式 先求出n可以字典序最大的表示 设f[i][0/1]表示第i个斐波那契数选或者不选 如果当前数不选,那就选比他小的两个数,否则 ...

  6. bzoj 2561: 最小生成树【最小割】

    看错题了以为多组询问吓得不行-- 其实还挺好想的,就是数据范围一点都不网络流.把U作为s,V作为t,以最小生成树为例,(U,V,L)要在最小生成树上,就要求所有边权比L小的边不能连通(U,V)所在的联 ...

  7. UVA - 10859 Placing Lampposts 放置街灯

    Placing Lampposts 传送门:https://vjudge.net/problem/UVA-10859 题目大意:给你一片森林,要求你在一些节点上放上灯,一个点放灯能照亮与之相连的所有的 ...

  8. java中WGS84坐标(ios)转换BD-09坐标(百度坐标)

    iPhone的GPS定位(CLLocationManager)获得的经纬坐标是基于WGS-84坐标系(世界标准),Google地图使用的是GCJ-02坐标系(中国特色的火星坐标系),百度的经纬坐标在G ...

  9. linux 文件查阅 cat、more、less、tail

    文件内容查阅1.cat由第一行开始显示文件内容2.tac:从最后一行开始显示,可以看出tac是cat的倒写形式.3.nl:显示的时候,顺便输出行号;4.more:一页一页地显示文件内容5.less:与 ...

  10. django urls路由匹配分发

    django urls路由匹配分发 一.urls配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是以这种方式告诉Django,对 ...