模板:有旋treap
有旋转的treap,其实rotate比较难理解
没关系,上板子:
题目还是普通平衡树
#include<iostream>
#include<cstdio>
#include<algorithm>
#define MAXN 100005
using namespace std;
int n,opt,x,root=0,np;
struct node{
int ch[MAXN][2],val[MAXN],size[MAXN],cnt[MAXN],prior[MAXN];
void update(int now){
size[now]=size[ch[now][0]]+size[ch[now][1]]+cnt[now];
}
void rotate(int &now,int dir){
int son=ch[now][dir^1];
ch[now][dir^1]=ch[son][dir];
ch[son][dir]=now;
update(now);
update(now=son);
}
void insert(int &now,int x){
if(!now){
now=++np;
size[now]=cnt[now]=1;
prior[now]=rand();
val[now]=x;
return ;
}
size[now]++;
if(val[now]==x){
cnt[now]++;
return ;
}
int d=x>val[now];
insert(ch[now][d],x);
if(prior[ch[now][d]]<prior[now]) rotate(now,d^1);
}
void remove(int &now,int num){
if(!now) return;
if(val[now]==num){
if(cnt[now]>1){
size[now]--;
cnt[now]--;
return;
}
if(!ch[now][0]||!ch[now][1]){
now=ch[now][0]+ch[now][1];
return;
}
int d=prior[ch[now][1]]<prior[ch[now][0]];
rotate(now,d^1);
remove(now,num);
return;
}
size[now]--;
int d=num>val[now];
remove(ch[now][d],num);
}
int get_rank(int now, int num){
if(!now) return 0;
if(num==val[now]) return size[ch[now][0]]+1;
int d=num>val[now];
if(d) return size[ch[now][0]]+cnt[now]+get_rank(ch[now][1],num);
return get_rank(ch[now][0],num);
}
int get_k(int now,int k){
while(now){
if(k<=size[ch[now][0]]) now=ch[now][0];
else if(k>size[ch[now][0]]+cnt[now]) k-=size[ch[now][0]]+cnt[now],now=ch[now][1];
else return val[now];
}
}
int get_pre(int now,int num){
if(!now) return -0x7fffffff;
if(num<=val[now]) return get_pre(ch[now][0],num);
return max(val[now],get_pre(ch[now][1],num));
}
int get_next(int now,int num){
if(!now) return 0x7fffffff;
if(num>=val[now]) return get_next(ch[now][1],num);
return min(val[now],get_next(ch[now][0],num));
}
}treap;
int main(){
scanf("%d",&n);
while(n--){
scanf("%d%d",&opt,&x);
if(opt==1) treap.insert(root,x);
else if(opt==2) treap.remove(root, x);
else if(opt==3) printf("%d\n",treap.get_rank(root,x));
else if(opt==4) printf("%d\n",treap.get_k(root,x));
else if(opt==5) printf("%d\n",treap.get_pre(root,x));
else if(opt==6) printf("%d\n",treap.get_next(root,x));
}
return 0;
}
模板:有旋treap的更多相关文章
- 模板 - 无旋Treap
一般而言作为一棵平衡树只需要插入,删除,值求排名,排名求值,前驱,后继,六个接口. #include<bits/stdc++.h> using namespace std; typedef ...
- [模板] 无旋Treap (C++ class)
注意!本帖不是算法介绍!只是贴代码(逃) //嫌stdlib的rand太慢,手打了一个 /* Author: hotwords */ typedef unsigned int tkey; class ...
- 模板——无旋Treap
#include "bits/stdc++.h" using namespace std; inline int read(){ ,k=;char ch=getchar(); :, ...
- 平衡树简单教程及模板(splay, 替罪羊树, 非旋treap)
原文链接https://www.cnblogs.com/zhouzhendong/p/Balanced-Binary-Tree.html 注意是简单教程,不是入门教程. splay 1. 旋转: 假设 ...
- [模板] 平衡树: Splay, 非旋Treap, 替罪羊树
简介 二叉搜索树, 可以维护一个集合/序列, 同时维护节点的 \(size\), 因此可以支持 insert(v), delete(v), kth(p,k), rank(v)等操作. 另外, prev ...
- 无旋treap的简单思想以及模板
因为学了treap,不想弃坑去学splay,终于理解了无旋treap... 好像普通treap没卵用...(再次大雾) 简单说一下思想免得以后忘记.普通treap因为带旋转操作似乎没卵用,而无旋tre ...
- 模板 - 数据结构 - 可持久化无旋Treap/PersistentFHQTreap
有可能当树中有键值相同的节点时,貌似是要对Split和Merge均进行复制的,本人实测:只在Split的时候复制得到了一个WA,但只在Merge的时候复制还是AC,可能是恰好又躲过去了.有人说假如确保 ...
- 洛谷 - P3391 【模板】文艺平衡树(Splay) - 无旋Treap
https://www.luogu.org/problem/P3391 使用无旋Treap维护序列,注意的是按顺序插入的序列,所以Insert实际上简化成直接root和Merge合并,但是假如要在序列 ...
- 非旋 treap 结构体数组版(无指针)详解,有图有真相
非旋 $treap$ (FHQ treap)的简单入门 前置技能 建议在掌握普通 treap 以及 左偏堆(也就是可并堆)食用本blog 原理 以随机数维护平衡,使树高期望为logn级别, FHQ ...
- 2018.08.27 rollcall(非旋treap)
描述 初始有一个空集,依次插入N个数Ai.有M次询问Bj,表示询问第Bj个数加入集合后的排名为j的数是多少 输入 第一行是两个整数N,M 接下来一行有N个整数,Ai 接下来一行有M个整数Bj,保证数据 ...
随机推荐
- python 随便笔记
1 判断字符串中是否有数字 i.isdigit()==True else False #判断是否是数字i.isalpha()==True else False #判断是否是字母 i.isspace() ...
- Google Chrome浏览器安装xpath helper插件
1. 图中桌面的两个2.0.2_0文件就是xpath helper插件. --------------------------------------------------------------- ...
- 07_mybatis延迟加载
1. 延迟加载 resultMap可以实现高级映射(使用association.collection实现一对一及一对多映射),association.collection具备延迟加载功能. 需求: ...
- <scrapy爬虫>scrapy命令行操作
1.mysql数据库 2.mongoDB数据库 3.redis数据库 1.创建项目 scrapy startproject myproject cd myproject 2.创建爬虫 scrapy g ...
- 牛客集训第七场J /// DP
题目大意: 在矩阵(只有52种字符)中找出所有不包含重复字符的子矩阵个数 #include <bits/stdc++.h> #define ll long long using names ...
- POJ 1743-POJ - 3261~后缀数组关于最长字串问题
POJ 1743 题意: 有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1~~88范围内的整数,现在要找一个重复的主题.“主题”是整个音符序列的一个子串,它需 ...
- java_Map集合
import java.util.HashMap; public class MapTest { /** * 1.Map集合是双列几个,一个元素包含两个值(key,value) * 2.Map集合中的 ...
- 2018-8-10-win10-uwp-验证输入-自定义用户控件
title author date CreateTime categories win10 uwp 验证输入 自定义用户控件 lindexi 2018-08-10 19:16:51 +0800 201 ...
- thinkphp 数据创建
在进行数据操作之前,我们往往需要手动创建需要的数据,例如对于提交的表单数据: // 获取表单的POST数据 $data['name'] = $_POST['name']; $data['email'] ...
- UNION操作用于合并两个或多个 SELECT 语句的结果集。
UNION操作用于合并两个或多个 SELECT 语句的结果集. 大理石平台价格 使用示例: $Model->field('name') ->table('think_user_0') -& ...