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 ;
}

最新文章

  1. 早上遇到err_content_decoding_fail错误
  2. linux 学习 12 服务管理
  3. SAP ALV显示并打印(非OO方式)
  4. ASP.NET 为GridView添加序号列,且支持分页连续累计显示
  5. 获取本机的IP地址(局域网)与主机名称
  6. 【转】Mac OS X开机启动Path had bad permissions错误解决方案
  7. Yii 框架创建自己的 web 应用
  8. C# using SendMessage, problem with WM_COPYDATA z
  9. ios 通过代码调节屏幕亮度
  10. Android(java)学习笔记177:BroadcastReceiver之 应用程序安装和卸载 的广播接收者
  11. 关于UITableview刷新笔记
  12. 关于IOC容器的一些个人理解
  13. 初识SEO
  14. Fiddler模拟低速网络
  15. jquery实现同时展示多个tab标签+左右箭头实现来回滚动
  16. Centos7 搭建Gitlab服务器并配置项目全过程
  17. svn备份与还原_脚本_(dump命令)
  18. python标准库介绍——3 stat 模块详解
  19. CSS之少用继承,多用组合
  20. Prim算法---最小生成树

热门文章

  1. 最简单的基于JSP标准标签库的增删改查
  2. windows2003 iis php 配置后无法执行php页面
  3. iOS开发:http中的get和post请求
  4. 笔记本中的archlinux调节亮度
  5. iOS socket 笔记
  6. Wireshark工控协议
  7. 【实践】用js 实现 jq 的removeClass 方法
  8. PHP开发中的缓存技术汇总
  9. 深入理解JavaScript闭包【译】
  10. java多线程 生产者消费者模式