Treap
treap模板
期望复杂度为O(nlogn)
带合并的treap期望复杂度为O(nlognlogn)
#include <bits/stdc++.h>
const int N = 1e6+;
struct tree{
int l, r;//左右儿子节点编号
int num;//当前节点的数字
int s;//以当前节点为根的子树的节点数
int sum;//当前节点的数字的数量
int rnd;//随机优先级
}tr[N];
int rt, cnt, t1, t2;
void updata(int &k){
int &l = tr[k].l, &r = tr[k].r;
tr[k].s = tr[l].s+tr[r].s+tr[k].sum;
}
void lturn(int &k){
int t = tr[k].r;
tr[k].r = tr[t].l; tr[t].l = k; tr[t].s = tr[k].s;
updata(k); k = t;
}
void rturn(int &k){
int t = tr[k].l;
tr[k].l = tr[t].r; tr[t].r = k; tr[t].s = tr[k].s;
updata(k); k = t;
}
void insert(int &k, int x){
if(!k){
k = ++cnt;
tr[k].l = tr[k].r = ;
tr[k].num = x;
tr[k].s = tr[k].sum = ;
tr[k].rnd = rand();
return ;
}
tr[k].s++;
int &l = tr[k].l, &r = tr[k].r;
if(x < tr[k].num){
insert(l, x);
if(tr[l].rnd < tr[k].rnd) rturn(k);
}
else if(x > tr[k].num){
insert(r, x);
if(tr[r].rnd < tr[k].rnd) lturn(k);
}
else tr[k].sum++;
}
void del(int &k, int x){
if(!k) return ;
int &l = tr[k].l, &r = tr[k].r;
if(x == tr[k].num){
if(tr[k].sum > ){
tr[k].sum--; tr[k].s--;
return ;
}
if(l*r == ) k = l+r;
else{
if(tr[l].rnd < tr[r].rnd) rturn(k);
else lturn(k);
del(k, x);
}
}
else{
tr[k].s--;
if(x > tr[k].num) del(r,x);
else del(l,x);
}
}
int find1(int &k, int x){//查询 < x 的个数
if(!k) return ;
int &l = tr[k].l, &r = tr[k].r;
if(tr[k].num == x) return tr[l].s;
if(tr[k].num > x) return find1(l, x);
if(tr[k].num < x) return tr[l].s+tr[k].sum+find1(r,x);
}
int find2(int &k, int x){//查询排名为x的数
if(!k) return ;
int &l = tr[k].l, &r = tr[k].r;
if(tr[l].s+ <= x&&tr[l].s+tr[k].sum >= x) return tr[k].num;
if(tr[l].s >= x) return find2(l, x);
if(tr[l].s+tr[k].sum < x) return find2(r, x-tr[l].s-tr[k].sum);
}
//以下不常用
void pred(int &k, int x){//t1 = 小于x的最大数
if(!k) return ;
int &l = tr[k].l, &r = tr[k].r;
if(tr[k].num < x){
t1 = tr[k].num;
pred(r, x);
}
else pred(l, x);
}
void succ(int &k, int x){//t2 = 大于x的最小数
if(!k) return ;
int &l = tr[k].l, &r = tr[k].r;
if(tr[k].num > x){
t2 = tr[k].num;
succ(l, x);
}
else succ(r, x);
}
void mergeto(int &src, int &dest){//合并堆, 请确保src为根的子树大小小于dest, 需要O(nlogn)空间
if(tr[src].l) mergeto(tr[src].l, dest);
if(tr[src].r) mergeto(tr[src].r, dest);
insert(dest, tr[src].num);
src = ;
}
int main(){
srand(time());
int n;
scanf("%d", &n);
rt = cnt = ;//init
for(int i = , opt, x; i <= n; i++){
scanf("%d%d", &opt, &x);
t1 = t2 = ;
switch(opt){
case :insert(rt, x); break;//插入一个x
case :del(rt, x); break;//删除一个x
case :printf("%d\n", find1(rt, x)); break;//统计小于x的个数
case :printf("%d\n", find2(rt, x)); break;//求排第x的数
case :pred(rt, x); printf("%d\n", t1); break;
case :succ(rt, x); printf("%d\n", t2); break;
}
}
return ;
}
Treap的更多相关文章
- fhq treap最终模板
新学习了fhq treap,厉害了 先贴个神犇的版, from memphis /* Treap[Merge,Split] by Memphis */ #include<cstdio> # ...
- BZOJ 1691: [Usaco2007 Dec]挑剔的美食家 [treap 贪心]
1691: [Usaco2007 Dec]挑剔的美食家 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 786 Solved: 391[Submit][S ...
- BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 [treap hash]
1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1318 Solved: 498[Submit][ ...
- 非旋treap模板
bzoj3580 非旋转treap 在大神教导下发现split一段区间时先split右边再split左边比较好写 #include <cstdio> #include <cstdli ...
- POJ2985 The k-th Largest Group[树状数组求第k大值+并查集||treap+并查集]
The k-th Largest Group Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 8807 Accepted ...
- [普通平衡树treap]【学习笔记】
3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 9046 Solved: 3840[Submit][Sta ...
- UVALive5031 Graph and Queries(Treap)
反向操作,先求出最终状态,再反向操作. 然后就是Treap 的合并,求第K大值. #include<cstdio> #include<iostream> #include< ...
- 【Treap】bzoj1588-HNOI2002营业额统计
一.题目 Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司 ...
- hdu 4585 Shaolin treap
Shaolin Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Problem ...
- treap 模版
struct Treap { struct node { node *son[]; int key,siz,wei,cnt; node(int _key,node *f) { son[]=son[]= ...
随机推荐
- MongoDB win安装后无法远程连接访问
mongoDB安装后无法远程连接访问,原因是端口没有开放允许连接的权限 开启允许连接的权限: 管理工具-高级win防火墙
- C++之路进阶——codevs2306(晨跑)
2306 晨跑 2009年省队选拔赛山东 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 大师 Master 题目描述 Description Elaxia最近迷恋 ...
- operator->和operator->*
->和->*都是C++中定义的可重载的运算符,其中:->称为成员选择符(member selection),而->*称为成员指针选择符(pointer-to-member se ...
- Win7开机登陆密码忘记了?不必重做系统(详图)
1)如果是普通账户密码忘了.方法:重新启动电脑,启动到系统登录界面时,同时按住Ctrl+Alt键,然后连击Del键两次,会出现新的登录界面,用户名处输入“Administrator”密码为空,回车即 ...
- Windows Phone 十四、磁贴通知
磁贴(Tile) Windows Phone 磁贴种类: 小尺寸 SmallLogo:71x71: Square71x71 中等 Logo:150x150: Square150x150 宽 WideL ...
- .net之工作流工程展示及代码分享(一)工作流表单
Workflow表单的作用是能够在客户端进行表单设计,然后在流程中动态开放哪些输入框可以供用户填写. 在这里我扩展了一个常用的WebEditor工具——KindEditor,能够插入自定义的html符 ...
- docker命令小记
最近工作需要,对docker稍微了解了一下,大部分内容网上都有各种各样的教程.有两个稍微特殊的命令这里记录一下: 1. rename image的命令 从各种私有镜像下载后用docker images ...
- link和@import的区别、及各自的应用
面试的过程中遇到的问题,当时自己回答的感觉自己心里还是很满意的,但是回来百度查看后才知道自己回答的有多么的糟糕: 下面我这这个知识点做一些总结的书面说明,为了少走点弯路,多涨点见识吧. 首先我们要了解 ...
- 视频软件TurboDemo 教程:如何为视频添加旁白和音乐
在前面的文章中,已经对视频软件TurboDemo如何快速的捕捉屏幕和视频编辑做了一些了解,本文主要来了解如何为视频添加旁白和音乐. Slide Timing 在Player Controls窗口中的单 ...
- css样式控制 字符个数,多余的字用省略号代替
大家好,我是小菜 前端 ,技术不高,正在努力中充电!希望大家多多指教 <div class="show">大家好,我是小菜 前端 ,技术不高,正在努力中充电!希望大家多 ...