珂朵莉树(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 ...
随机推荐
- 浅谈JAVA中如何利用socket进行网络编程(二)
转自:http://developer.51cto.com/art/201106/268386.htm Socket是网络上运行的两个程序间双向通讯的一端,它既可以接受请求,也可以发送请求,利用它可以 ...
- package-lock.json到底是干嘛的?(转载)
package-lock.json到底是干嘛的? https://mp.weixin.qq.com/s/NaVVljKrQAFmHMdbkaYmPg## nvm-windows https://git ...
- Educational Codeforces Round 52 (Rated for Div. 2) F. Up and Down the Tree 树型DP
题面 题意:给你一棵树,你起点在1,1也是根节点,你每次可以选择去你子树的某个叶子节点,也可以选择,从叶子节点返回距离不超过k的一个根, 也就是说,你从1开始,向下跳,选择一个叶子(就是没有子树的节点 ...
- PostgreSQL 9.6.2版本在centOS下的安装和配置
1.如果有用yum安装过旧版,卸载掉: yum remove postgresql* 2.更新一下yum: sudo yum update 3.去 官网 找到 适合你系统 的资源的下载地址,然后使用w ...
- Python圈中的符号计算库-Sympy(转载)
<本文来自公众号“大邓带你玩python”,转载> import math math.sqrt(8) 2.8284271247461903 我们看看Python中结果 math.sqrt( ...
- phpstudy 集成的mysql 无法启动
问题产生: 安装好phpstudy后,Apache可以启动,Mysql无法启动. 解决方法: 之前已经装过Mysql,要把系统服务里面的MySQL删除,留下MySQLa服务. 在cmd命令行下输入: ...
- Django中的cookie和session实现
cookie from django.shortcuts import render, HttpResponse, redirect # 此装饰器的作用就是讲所有没有cookie验证的页面都需要验证后 ...
- [POJ2750]Potted Flower
Description The little cat takes over the management of a new park. There is a large circular statue ...
- 暑期训练狂刷系列——Foj 1894 志愿者选拔 (单调队列)
题目连接: http://acm.fzu.edu.cn/problem.php?pid=1894 解题思路: 因为出队和入队都满足队列的性质,优先单调队列的优先级有进入队列的顺序和人品的高低,在一段区 ...
- openssh安装、设置指定端口号、免密码登录、变量传递、防暴力破解
首先确保机器挂在好光盘镜像,然后查看软件包信息 [root@xuegod63 ~]# df -hFilesystem Size Used Avail Use% Mounted on/dev ...