本蒟蒻最近刚刚学会平衡树,特来写篇博客以加深印象。
(我的意思是若写的不好望各位奆佬多多包含!)
题目描述
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
- 插入 x 数
- 删除 x 数(若有多个相同的数,因只删除一个)
- 查询 x 数的排名(排名定义为比当前数小的数的个数 +1 。若有多个相同的数,因输出最小的排名)
- 查询排名为 x 的数
- 求 x 的前驱(前驱定义为小于 x ,且最大的数)
- 求 x 的后继(后继定义为大于 x ,且最小的数)
输入输出格式
输入格式:
第一行为 n ,表示操作的个数,下面 n 行每行有两个数 opt 和 x , opt 表示操作的序号
输出格式:
对于操作 3,4,5,6 每行输出一个数,表示对应答案
输入输出样例
输入样例#1:
10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
输出样例#1:
106465
84185
492737
样例是真的大啊!=_=
大的都不像是样例了!
好了,现在开始讲解!
首先讲解我用的变量吧!!
int ch[maxn][2] ;//存儿子,ch[][0]存左儿子,ch[][1]存右儿子
int f[maxn] ;//存爹
int size[maxn] ;//存这个点的子树大小
int cnt[maxn] ;//存权值
int key[maxn] ;//存数值
int sz,root ;//整棵树的大小和树根
首先,一切从简单的开始讲起,首先说输入(不想看的向下翻)
首先输入一个数n,然后下面n行,每行输入一个操作标记和数。
int n,opt,x;
scanf("%d",&n);
for (int i=1;i<=n;++i){
scanf("%d%d",&opt,&x);
switch(opt){
case 1: 插入
case 2: 删除
case 3: 找数的排名
case 4: 找排名的数
case 5: 找前驱
case 6: 找后继
}
}
然后在依次讲解操作
操作1:插入
以我之见,插入这个是最容易打错的操作(我就打错了好几次)。
总体的思路是:如果遇到一个与x数值相同的数,就把数的权值加一。
还有一些特殊的情况:
1.