博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
普通平衡树(bzoj 3224)
阅读量:5096 次
发布时间:2019-06-13

本文共 2666 字,大约阅读时间需要 8 分钟。

Description

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:

1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)

Input

第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

Output

对于操作3,4,5,6每行输出一个数,表示对应答案

Sample Input

10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598

Sample Output

106465
84185
492737

HINT

 

1.n的数据范围:n<=100000
2.每个数的数据范围:[-1e7,1e7]
数据如下http://pan.baidu.com/s/1jHMJwO2
/*  一个平衡树的模板写了一上午了,能犯的错误基本都犯了。。。  首先没加哨兵,再就是删除操作时没有更新sz(这个巨坑),真是长记性了。 */#include
#include
#define N 100010using namespace std;int son[N][2],fa[N],val[N],cnt[N],sz[N],m,rt,size;void pushup(int x){ sz[x]=sz[son[x][0]]+sz[son[x][1]]+cnt[x];}void rotate(int x,int &k){ int y=fa[x],z=fa[y],l,r; if(son[y][0]==x) l=0;else l=1;r=l^1; if(y==k) k=x; else { if(son[z][0]==y) son[z][0]=x; else son[z][1]=x; } fa[x]=z;fa[y]=x;fa[son[x][r]]=y; son[y][l]=son[x][r];son[x][r]=y; pushup(y);pushup(x);}void splay(int x,int &k){ while(x!=k){ int y=fa[x],z=fa[y]; if(y!=k){ if((son[y][0]==x)^(son[z][0]==y)) rotate(x,k); else rotate(y,k); } rotate(x,k); }}void insert(int v){ int k=rt,y=0; while(k&&val[k]!=v) y=k,k=son[k][v>val[k]]; if(k) cnt[k]++; else { k=++size;sz[k]=1;cnt[k]=1;fa[k]=y;val[k]=v; if(y) son[y][v>val[y]]=k; } splay(k,rt);}void find1(int v){
//查找v的位置 int k=rt;if(!k)return; while(son[k][v>val[k]]&&val[k]!=v) k=son[k][v>val[k]]; splay(k,rt);}int find2(int x){
//查找排名为x的数 x++; int k=rt; if(sz[k]
=x) return k; if(sz[son[k][0]]>=x) k=son[k][0]; else x-=(sz[son[k][0]]+cnt[k]),k=son[k][1]; } return k;}int nxt(int x,int f){ find1(x); if((val[rt]>x&&f)||val[rt]
1){cnt[x]--;sz[x]--;return;} if(!son[x][0]||!son[x][1]){ rt=son[x][0]+son[x][1]; } else { k=son[x][1]; while(son[k][0])k=son[k][0];sz[k]+=sz[son[x][0]]; fa[son[x][0]]=k;son[k][0]=son[x][0]; rt=son[x][1]; } fa[rt]=0;splay(k,rt);}int main(){ insert(-0x7fffffff);insert(0x7fffffff); scanf("%d",&m); for(int i=1;i<=m;i++){ int opt,x;scanf("%d%d",&opt,&x); if(opt==1) insert(x); if(opt==2) del(x); if(opt==3) find1(x),printf("%d\n",sz[son[rt][0]]); if(opt==4) printf("%d\n",val[find2(x)]); if(opt==5) printf("%d\n",val[nxt(x,0)]); if(opt==6) printf("%d\n",val[nxt(x,1)]); } return 0;}

 

转载于:https://www.cnblogs.com/harden/p/6403543.html

你可能感兴趣的文章
jzoj100029
查看>>
起底多线程同步锁(iOS)
查看>>
[BZOJ 1951] 古代猪文
查看>>
HTML介绍
查看>>
Template_5模板拾遗1
查看>>
2017/11/7 Leetcode 日记
查看>>
Snap.svg中transform旋转值的“r+数组”表现形式
查看>>
数据库系统原理——ER图转换成关系模式集的算法
查看>>
SPOJ KPSUM ★(数位DP)
查看>>
什么时候使用引用?和什么时候使用指针
查看>>
layout layout_alignLeft跟layout_toLeftOf
查看>>
CSS: inline-block的应用和float块高度塌陷
查看>>
【iOS】字号问题
查看>>
Redis
查看>>
如何让一台IIS服务器实现多个网站https访问
查看>>
02-进程、线程、虚拟内存、文件
查看>>
评价在使用的输入法
查看>>
iOS程序内实现版本更新
查看>>
微信小程序-存取本地缓存
查看>>
xsd 和 wsdl
查看>>