您需要写一种数据结构,来维护一些数,其中需要提供以下操作:
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. 使用CROS解决跨域问题

    使用jq的话,设置ajax这两个属性即可. 第一个为使用crossDomain,第二个属性使其可以传输cookie $.ajaxSetup({ crossDomain: true, xhrFields ...

  2. 二叉搜索树BST

    //遍历 void print(int p){ if(!p) return; print(left[p]); printf("%d\n",a[p]); print(right[p] ...

  3. C# WinForm开发系列 - Crystal Report水晶报表

    转自:ttp://www.cnblogs.com/peterzb/archive/2009/07/11/1521325.html 水晶报表(Crystal Report)是业内最专业.功能最强的报表系 ...

  4. SQL 查看表字段及说明

    select A.comments,A.column_name,B.DATA_TYPE||'('||B.DATA_LENGTH||')' from user_col_comments A inner ...

  5. sqlserver 循环取时间

    declare @str date; set @str='2015-01-08'; while DATEDIFF([day], @str , '2015-02-01')>0 begin sele ...

  6. Django相关面试题

    Django框架的生命请求周期 浏览器上输入地址,回车然后发生了什么? => Http请求生命周期 ? 什么是wsgi 以及作用? 中间件 中间件的执行流程? 中间件的执行流程? 说一下Djan ...

  7. c2d遮罩

    ClippingNode 节点 ClippingNode setStencil 设置模版  只有模版的区域显示此节点内容 使用了Opengl的 模板测试  http://www.cnblogs.com ...

  8. luogu P2470 [SCOI2007]压缩

    传送门 dalao们怎么状态都设的两维以上啊?qwq 完全可以一维状态的说 设\(f[i]\)为前缀i的答案,转移就枚举从前面哪里转移过来\(f[i]=min(f[j-1]+w(j,i))(j\in ...

  9. windows Apache 环境下配置支持HTTPS的SSL证书

    windows Apache 环境下配置支持HTTPS的SSL证书 1.准备工作 1)在设置Apache + SSL之前, 需要做: 安装Apache, 下载安装Apache时请下载带有SSL版本的A ...

  10. Python非空即真,非零即真

    非空即真,非零即真 #1. 非空即真(只要输入不为空就是真) #username =''(空字典.空字符串.空元组都算空) # a= '' # b=[] # c={} # d=None (返回值是No ...