珂朵莉树(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 ...
随机推荐
- 关于XAMPP Apache无法启动问题解决方案
安装好XAMPP后,启动Apache服务启动失败,然后从xampp安装目录下执行apache_start.bat文件,如下图 显示443端口被占用. 解决方法: 启动cmd,输入netstat -a ...
- Pascal之计算小系统
program Project16; {$APPTYPE CONSOLE} VAR n,i,k,score,b,a:integer; answer,c:real; ch:char; Begin rep ...
- Windows NT/NTLM 加密
Hash,一般翻译为“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射,pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值.这种转换是一种压缩映射,也就是散 ...
- P5089 [eJOI2018]元素周期表(并查集)
传送门 以后看到棋盘要么黑白染色要么二分图! 我们考虑对行列建二分图,如果\(i\)行\(j\)列有,就把\(i\)和\(j+n\)连起来 我们要让它变成一张完全二分图.考虑条件\((i_1,j_1+ ...
- 洛谷P3250 [HNOI2016]网络(整体二分+树状数组+树剖)
传送门 据说正解是树剖套堆???然而代码看着稍微有那么一点点长…… 考虑一下整体二分,设当前二分到的答案为$mid$,如果所有大于$mid$的边都经过当前点$x$,那么此时$x$的答案必定小于等于$m ...
- SpringMVC分页查询无法直接将对象转换成json的解决办法(报org.springframework.http.converter.HttpMessageNotWritableException: No converter found for return value of type:错)
在用ajax获得分页数据时,无法将获取的值赋值给input标签,在修改用户信息时不显示用户已经注册的信息,百度可知 springmvc处理分页数据返回的对象时,无法直接将对象转换成json,会报org ...
- 博弈 HDOJ 4371 Alice and Bob
题目传送门 题意:Alice和 Bob轮流写数字,假设第 i 次的数字是S[i] ,那么第 i+1 次的数字 S[i+1] = S[i] + d[k] 或 S[i] - d[k],条件是 S[i+1] ...
- jmeter(十七)逻辑控制器
JMeter中的Logic Controller用于为Test Plan中的节点添加逻辑控制器. JMeter中的Logic Controller分为两类:一类用来控制Test Plan执行过程中节点 ...
- 191 Number of 1 Bits 位1的个数
编写一个函数,输入是一个无符号整数,返回的是它所有 位1 的个数(也被称为汉明重量).例如,32位整数 '11' 的二进制表示为 00000000000000000000000000001011,所以 ...
- 如何使用mysqldump命令导入导出数据库下的数据或表结构(远程or本地都适合)
不多说,直接上干货! https://www.cloudera.com/documentation/manager/5-1-x/Cloudera-Manager-Installation-Guide/ ...