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的更多相关文章

  1. fhq treap最终模板

    新学习了fhq treap,厉害了 先贴个神犇的版, from memphis /* Treap[Merge,Split] by Memphis */ #include<cstdio> # ...

  2. BZOJ 1691: [Usaco2007 Dec]挑剔的美食家 [treap 贪心]

    1691: [Usaco2007 Dec]挑剔的美食家 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 786  Solved: 391[Submit][S ...

  3. BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 [treap hash]

    1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1318  Solved: 498[Submit][ ...

  4. 非旋treap模板

    bzoj3580 非旋转treap 在大神教导下发现split一段区间时先split右边再split左边比较好写 #include <cstdio> #include <cstdli ...

  5. POJ2985 The k-th Largest Group[树状数组求第k大值+并查集||treap+并查集]

    The k-th Largest Group Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8807   Accepted ...

  6. [普通平衡树treap]【学习笔记】

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 9046  Solved: 3840[Submit][Sta ...

  7. UVALive5031 Graph and Queries(Treap)

    反向操作,先求出最终状态,再反向操作. 然后就是Treap 的合并,求第K大值. #include<cstdio> #include<iostream> #include< ...

  8. 【Treap】bzoj1588-HNOI2002营业额统计

    一.题目 Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司 ...

  9. hdu 4585 Shaolin treap

    Shaolin Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Problem ...

  10. treap 模版

    struct Treap { struct node { node *son[]; int key,siz,wei,cnt; node(int _key,node *f) { son[]=son[]= ...

随机推荐

  1. java 反射机制

    1.反射机制是什么: (1)反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能 ...

  2. codeforce 121E - Lucky Array

    10^4以内只由4和7构成的数字只有31种,那么做法就很简单了,求出每个数字与其最接近的幸运数的差值,然后建立线段树,线段树维护区间最小值和最小值个数,如果操作过程中最小值<0,那么就去对差值进 ...

  3. Docker镜像的管理和创建

    1. Docker镜像和Docker容器:      Docker镜像实际上是一系列的文件系统,通常的Linux系统一般是两层文件系统,bootfs和rootfs,bootfs就是bootloader ...

  4. PARENT VIEW INVALIDATE

    如果启动display list,parentview 调用invalidate,子view是不会是去调用onDraw的,因为直接调用displaylist了,如果parentview认为子view应 ...

  5. python函数基础 与文件操作

    函数的定义 函数是通过赋值传递的,参数通过赋值传递给函数.def语句将创建一个函数对象并将其赋值给一个变量名,def语句的一般格式如下: def function_name(arg1,arg2[,.. ...

  6. Java反射遍历数组

    日志中有时候需要查看数组中的值,但是重载很多的打印函数,觉得很别扭.所以想通过反射,获取数组中的值,打印出来.Java提供了数组反射操作的类,之前没有关注过,提供的方法简单易用. public sta ...

  7. Hi, there!

    Wish you a happy day~我们一起玩WEB前端!^ ^

  8. CSS、HTML5、JS

    [att*=value]{}包含value属性的所有元素样式.[id*=div]{} a[href$=jpg]:after{} [att^=value]{}开头字符包含value属性的所有元素样式 [ ...

  9. oracle迁移postgres之-Ora2Pg

    描述 Ora2Pg:甲骨文PostgreSQL数据库模式转换器是一个免费的工具用于Oracle数据库迁移到PostgreSQL兼容模式.它连接Oracle数据库,扫描它自动提取其结构或数据,然后生成S ...

  10. redis.conf配置详细翻译解析

    # redis 配置文件示例 # 当你需要为某个配置项指定内存大小的时候,必须要带上单位, # 通常的格式就是 1k 5gb 4m 等酱紫: # # 1k => 1000 bytes # 1kb ...