P5076 【深基16.例7】普通二叉树(简化版)题解

本文介绍了如何使用C++的BST数据结构和multiset容器来处理数集的插入、查询、前驱、后继和排名操作,包括详细的操作步骤和示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

您需要写一种数据结构,来维护一些数(都是绝对值10^{9}以内的数)的集合,最开始时集合是空的。其中需要提供以下操作,操作次数q不超过10^{4}

  1. 定义数x的排名为集合中小于x的数的个数+1。查询数x的排名。注意x不一定在集合里。
  2. 查询排名为x(x≥1) 的数。保证集合里至少有x个数。
  3. 求x的前驱(前驱定义为小于x,且最大的数)。若不存在则输出−2147483647。
  4. 求x的后继(后继定义为大于x,且最小的数)。若不存在则输出2147483647。
  5. 插入一个数x,本题的数据保证插入前x不在集合中。

保证执行1,3,4操作时,集合中有至少一个元素。

输入输出格式

输入格式

第一行是一个整数q,表示操作次数。

接下来q行,每行两个整数op,x,分别表示操作序号以及操作的参数x。

输出格式

输出有若干行。对于操作1,2,3,4,输出一个整数,表示该操作的结果。

输入输出样例

输入样例

7
5 1
5 3
5 5
1 3
2 2
3 3
4 3

输出样例

2
3
1
5

解析1

BST,二叉搜索树,又叫二叉排序树,是一棵空树或具有以下几种性质的树:

  1. 若左子树不空,则左子树上所有结点的值均小于它的根结点的值

  2. 若右子树不空,则右子树上所有结点的值均大于它的根结点的值

  3. 左、右子树也分别为二叉排序树

  4. 没有权值相等的结点。

第4条在数据中遇到多个相等的数我们可以多加一个计数器,就是当前这个值出现了几遍。

那么我们的每一个节点都包含以下几个信息:

  1. 当前节点的权值,也就是序列里的数

  2. 左孩子的下标和右孩子的下标,如果没有则为0

  3. 计数器,代表当前的值出现了几遍

  4. 子树大小和自己的大小的和

节点是这样的:

struct node{
	int val,ls,rs,cnt,siz;
}tree[500010];

其中val是权值,ls /rs是左/右孩子的下标,cnt是当前的权值出现了几次,siz 是子树大小和自己的大小的和。

以下均以递归方式呈现。


插入:

x是当前节点的下标,v是要插入的值。要在树上插入一个v的值,就要找到一个合适v的位置,如果本身树的节点内有代表v的值的节点,就把该节点的计数器加1 ,否则一直向下寻找,直到找到叶子节点,这个时候就可以从这个叶子节点连出一个儿子,代表v的节点。具体向下寻找该走左儿子还是右儿子是根据二叉搜索树的性质来的。

void add(int x,int v)
{
	tree[x].siz++;
	//如果查到这个节点,说明这个节点的子树里面肯定是有v的,所以siz++
	i
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

互联网的猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值