P5076 【深基16.例7】普通二叉树(简化版)
题目描述
您需要写一种数据结构,来维护一些数( 都是 10^9109 以内的数字)的集合,最开始时集合是空的。其中需要提供以下操作,操作次数 qq 不超过 10^4104:
- 查询 xx 数的排名(排名定义为比当前数小的数的个数 +1+1。若有多个相同的数,因输出最小的排名)。
- 查询排名为 xx 的数。
- 求 xx 的前驱(前驱定义为小于 xx,且最大的数)。若未找到则输出 -2147483647−2147483647。
- 求 xx 的后继(后继定义为大于 xx,且最小的数)。若未找到则输出 21474836472147483647。
- 插入一个数 xx。
输入格式
无
输出格式
无
输入输出样例
输入 1
7
5 1
5 3
5 5
1 3
2 2
3 3
4 3
输出 1
2
3
1
5
二叉查找问题可以使用multiset,multiset满足可以重复的集合,但是是有序的,内部查找满足红黑树。lower_bound函数可以找出集合小于等于b的数,upper_bound函数可以找出集合中大于b的数
#include <set>
#include <cstdio>
#include <iostream>
using namespace std;
multiset<int> s;
int N, a, b;
int main() {
scanf("%d", &N);
s.insert(-2147483647);
s.insert(2147483647);
while(N--) {
scanf("%d%d", &a, &b);
if(a == 1) {
int cnt = 0;
auto it = s.lower_bound(b);
for(auto i = s.begin(); i != it; i++, cnt++);
printf("%d
", cnt);
} else if(a == 2) {
auto it = s.begin();
while(b--) it++;
printf("%d
", *it);
} else if(a == 3) {
auto it = --s.lower_bound(b); // 小于等于b的值
printf("%d
", *it);
} else if(a == 4) {
auto it = s.upper_bound(b); // 大于b的值
printf("%d
", *it);
} else if(a == 5) {
s.insert(b);
}
}
return 0;
}