treap模板
2015-08-10 11:35
459 查看
[Tyvj 1728]普通平衡树
★★ 输入文件:phs.in 输出文件:phs.out 简单对比
时间限制:1 s 内存限制:128 MB
【题目描述】
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
【输入格式】
第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)
【输出格式】
对于操作3,4,5,6每行输出一个数,表示对应答案
【样例输入】
10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
【样例输出】
106465
84185
492737
【提示】
1.n的数据范围:n<=100000
2.每个数的数据范围:[-1e7,1e7]
★★ 输入文件:phs.in 输出文件:phs.out 简单对比
时间限制:1 s 内存限制:128 MB
【题目描述】
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
【输入格式】
第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)
【输出格式】
对于操作3,4,5,6每行输出一个数,表示对应答案
【样例输入】
10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
【样例输出】
106465
84185
492737
【提示】
1.n的数据范围:n<=100000
2.每个数的数据范围:[-1e7,1e7]
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<ctime> using namespace std; struct node{ node *left,*right; int v,p,cnt,sz; }*root,*null=new node((node){null,null,0,0,0,0}); int in(){ int x=0; char ch=getchar(); bool f=true; while (ch<'0' || ch>'9'){ if (ch=='-') f=false; ch=getchar(); } while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar(); if (!f) x=-x; return x; } void push_up(node *x){ x->sz=x->left->sz+x->right->sz+x->cnt; } void lturn(node *&x){ node *y=x->right; x->right=y->left; y->left=x; y->sz=x->sz; push_up(x); x=y; } void rturn(node *&x){ node *y=x->left; x->left=y->right; y->right=x; y->sz=x->sz; push_up(x); x=y; } void Insert(node *&x,int k){ if (!x->sz){ x=new node; x->left=x->right=null; x->v=k; x->p=rand(); x->sz=x->cnt=1; return; } x->sz++; if (k==x->v) x->cnt++; else if (k>x->v){ Insert(x->right,k); if (x->right->p<x->p) lturn(x); } else { Insert(x->left,k); if (x->left->p<x->p) rturn(x); } } void Delete(node *&x,int k){ if (!x->sz) return; if (k==x->v){ if (x->cnt>1) x->cnt--,x->sz--; else if (!x->left->sz || !x->right->sz){ node *t=x; if (!x->left->sz) x=x->right; else x=x->left; delete t; } else if (x->left->p<x->right->p) rturn(x),Delete(x,k); else lturn(x),Delete(x,k); } else if (k<x->v) x->sz--,Delete(x->left,k); else x->sz--,Delete(x->right,k); } int Q_rank(node *x,int k){ if (!x->sz) return 0; if (k==x->v) return x->left->sz+1; else if (k<x->v) return Q_rank(x->left,k); else return Q_rank(x->right,k)+x->left->sz+x->cnt; } int Q_num(node *x,int k){ if (!x->sz) return 0; if (k<=x->left->sz) return Q_num(x->left,k); else if (k>x->left->sz+x->cnt) return Q_num(x->right,k-x->left->sz-x->cnt); else return x->v; } int Q_pro(node *x,int k,int c){ if (!x->sz) return c; if (k>x->v) return Q_pro(x->right,k,x->v); else return Q_pro(x->left,k,c); } int Q_suc(node *x,int k,int c){ if (!x->sz) return c; if (k<x->v) return Q_suc(x->left,k,x->v); else return Q_suc(x->right,k,c); } int main(){ freopen("phs.in","r",stdin); freopen("phs.out","w",stdout); int n=in(); root=null; srand(time(0)); while (n--){ int opt=in(),x=in(); switch (opt){ case 1:Insert(root,x); break; case 2:Delete(root,x); break; case 3:printf("%d\n",Q_rank(root,x)); break; case 4:printf("%d\n",Q_num(root,x)); break; case 5:printf("%d\n",Q_pro(root,x,0)); break; case 6:printf("%d\n",Q_suc(root,x,0)); break; } } return 0; }
相关文章推荐
- 最小生成树(prim&kruskal)模板
- 1.精度计算——大数阶乘
- 漫谈程序员(二)程序员保值的4个秘密
- xml 复用
- poj -1185 炮兵阵地 (经典状压dp)
- poj-1458 Common Subsequence
- dfs.datanode.max.xcievers&dfs.datanode.max.transfer.threads介绍
- 既可以滑动也可以点击切换(ViewPager跟Fragment)
- HDU 1496 Equations
- HDU 1827 强连通 缩点 Summer Holiday
- 华为OJ(找出字符串中第一个只出现一次的字符)
- hdu4813 Hard Code
- Android 进入后台触发的事件,一般用于APP屏幕解锁
- 这个月需要做什么?
- android 自定义ProgressBar
- 黑马程序员——注解
- 什么是SysWow64
- 编译android5.0源码的
- Ajax--跨域访问的三种方法
- jQuery解决input超多的表单提交