您需要写一种数据结构,来维护一些数,其中需要提供以下操作:
1. 插入x
2. 删除x(若有多个相同的数,因只删除一个)
3. 查询x的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)

1.n的数据范围:$n<=100000$
2.每个数的数据范围:$[-2e9,2e9]$

题解:

  二叉搜索树可以完成目标,但是单次操作的时间复杂度可能退化为线性

  因此使用平衡二叉树,$treap$(树堆)

  树堆是各类平衡树中,速度和代码复杂度比较均衡的一个

  速度比splay快且好写,比sbt,替罪羊慢但简单,个人觉得代码比较简单

  BZOJ

  LOJ

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e5+10;
const int maxm=1e6+10;
int casn,n,m,k;
#define nd treap[now]
#define ndl treap[treap[now].l]
#define ndr treap[treap[now].r]
#define ndt treap[tmp]
struct node {
int l,r,val,num,size,rnd;
}treap[maxn];
int cnt,root,ans;
inline void resize(int now){
nd.size=ndl.size+ndr.size+nd.num;
}
inline void rturn(int &now){
int tmp=nd.l;
nd.l=ndt.r,ndt.r=now;
ndt.size=nd.size;
resize(now);
now=tmp;
}
inline void lturn(int &now){
int tmp=nd.r;
nd.r=ndt.l,ndt.l=now;
ndt.size=nd.size;
resize(now);
now=tmp;
}
void insert(int &now,int val){
if(!now) {
now=++cnt;
nd=(node){0,0,val,1,1,rand()};
return ;
}
nd.size++;
if(val==nd.val)nd.num++;
else if(val>nd.val){
insert(nd.r,val);
if(ndr.rnd<nd.rnd) lturn(now);
}else{
insert(nd.l,val);
if(ndl.rnd<nd.rnd) rturn(now);
}
}
void erase(int &now,int val){
if(!now) return ;
if(val==nd.val){
if(nd.num>1){
nd.num--,nd.size--;
return ;
}
if(nd.r*nd.l==0) now=nd.l+nd.r;
else {
if(ndl.rnd<ndr.rnd) rturn(now);
else lturn(now);
erase(now,val);
}
}else {
nd.size--;
if(val>nd.val) erase(nd.r,val);
else erase(nd.l,val);
}
}
int query_rank(int now,int val){
if(!now) return 0;
if(val==nd.val)return ndl.size+1;
if(val>nd.val) return ndl.size+nd.num+query_rank(nd.r,val);
return query_rank(nd.l,val);
}
int query_val(int now,int rank){
if(!now) return 0;
if(rank<=ndl.size) return query_val(nd.l,rank);
if(rank-ndl.size<=nd.num) return nd.val;
return query_val(nd.r,rank-ndl.size-nd.num);
}
int query_pre(int now,int val){
if(!now) return ans;
if(val<=nd.val) return query_pre(nd.l,val);
ans=nd.val;
return query_pre(nd.r,val);
}
int query_sub(int now,int val){
if(!now) return ans;
if(val>=nd.val) return query_sub(nd.r,val);
ans=nd.val;
return query_sub(nd.l,val);
}
int main(){
//#define test
#ifdef test
freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);
#endif
int root=0;
scanf("%d",&n);
for(int i=1;i<=n;i++){
int a,b;
scanf("%d%d",&a,&b);
if(a==1) insert(root,b);
if(a==2) erase(root,b);
if(a==3) printf("%d\n",query_rank(root,b));
if(a==4) printf("%d\n",query_val(root,b));
if(a==5) printf("%d\n",query_pre(root,b));
if(a==6) printf("%d\n",query_sub(root,b));
}
#ifdef test
fclose(stdin);fclose(stdout);system("out.txt");
#endif
return 0;
}

BZOJ3224/LOJ104 普通平衡树 treap(树堆)的更多相关文章

  1. 可旋转Treap(树堆)总结

    树堆,在数据结构中也称Treap,是指有一个随机附加域满足堆的性质的二叉搜索树,其结构相当于以随机数据插入的二叉搜索树.其基本操作的期望时间复杂度为O(logn).相对于其他的平衡二叉搜索树,Trea ...

  2. treap(树堆)

    一棵treap是一棵修改了结点顺序的二叉查找树,如图,显示一个例子,通常树内的每个结点x都有一个关键字值key[x],另外,还要为结点分配priority[x],它是一个独立选取的随机数. 假设所有的 ...

  3. BZOJ 3224 TYVJ 1728 普通平衡树 [Treap树模板]

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 7390  Solved: 3122 [Submit][S ...

  4. BZOJ3224/LOJ104 普通平衡树 pb_ds库自带红黑树

    您需要写一种数据结构,来维护一些数,其中需要提供以下操作:1. 插入x2. 删除x(若有多个相同的数,因只删除一个)3. 查询x的排名(若有多个相同的数,因输出最小的排名)4. 查询排名为x的数5. ...

  5. BZOJ - 3224 Tyvj 1728 普通平衡树 (treap/树状数组)

    题目链接 treap及树状数组模板题. treap版: #include<bits/stdc++.h> using namespace std; typedef long long ll; ...

  6. 查找——图文翔解Treap(树堆)

    之前我们讲到二叉搜索树,从二叉搜索树到2-3树到红黑树到B-树. 二叉搜索树的主要问题就是其结构与数据相关,树的深度可能会非常大,Treap树就是一种解决二叉搜索树可能深度过大的还有一种数据结构. T ...

  7. 树堆(Treap)学习笔记 2020.8.12

    如果一棵二叉排序树的节点插入的顺序是随机的,那么这样建立的二叉排序树在大多数情况下是平衡的,可以证明,其高度期望值为 \(O( \log_2 n )\).即使存在一些极端情况,但是这种情况发生的概率很 ...

  8. HihoCoder 1325 平衡树·Treap

    HihoCoder 1325 平衡树·Treap 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说 ...

  9. 真·浅谈treap树

    treap树是一种平衡树,它有平衡树的性质,满足堆的性质,是二叉搜索树,但是我们需要维护他 为什么满足堆的性质?因为每个节点还有一个随机权值,按照随机权值维持这个堆(树),可以用O(logn)的复杂度 ...

随机推荐

  1. vscode 配置踩坑记

    vscode-easy-less 遇到问题最好的解决方式是看官网文档,切记!!! 在web开发当中,经常会写less然后编译成css,当然在VS Code当中也有这样的插件(EasyLess), 但是 ...

  2. BFC规范

    BFC规范 BFC规范是什么? BFC规范也叫块级格式化上下文.是指一个独立的容器. 如何触发BFC? 我们可以通过一下几种方式触发BFC 1.通过浮动触发:float(除none) 2.通过绝对\固 ...

  3. 学习总结:CSS(一)定义方式、选择器、选择器权重

    一.CSS的定义方式 1.内部样式:<style></style> 2.行间样式:<div style="width:100px;height:100px;&q ...

  4. 【转载】C# 获取系统时间及时间格式

    https://www.cnblogs.com/xjtrab/articles/1878353.html

  5. 21.Buffer Pool与压缩页/CheckPoint/LSN

    一. 思考题解析• 查看Buffer Pool中的Flush List不要在线上操作该SQL语句,开销较大 SELECT pool_id, lru_position, space, page_numb ...

  6. C# FTPHelper工具类

    /// <summary> /// Ftp /// </summary> public class FtpFileOperation { private string _ftp ...

  7. oracle汉字转拼音(获得全拼/拼音首字母/拼音截取等)

        oracle汉字转拼音(获得全拼/拼音首字母/拼音截取等)   效果如下: Oracle 字符集 GBK 没有问题 , UTF -8 需要修改一下   Sql代码   --oracle汉字转拼 ...

  8. dbms_redefinition在线重定义表结构 可以在表分区的时候使用

    dbms_redefinition在线重定义表结构 (2013-08-29 22:52:58) 转载▼ 标签: dbms_redefinition 非分区表转换成分区表 王显伟 在线重定义表结构 在线 ...

  9. 迅为开发板4412开发板-ANROID系统的烧写方法分享

    详情了解: http://topeetboard.com   更多了解:https://arm-board.taobao.com 一.OTG接口烧写方式 通过该方式可以烧写 Android4.0.3 ...

  10. RHEL 6.4 通过mysql安装文件安装mysql

    参考文章:http://www.linuxidc.com/Linux/2013-12/93507.htm 1.首先下载mysql安装文件 我是下载的最新版的5.6 2. 以RPM方式安装MySQL 在 ...