首页 > 其他分享 >平衡树

平衡树

时间:2022-10-07 07:55:44浏览次数:47  
标签:return get int rank key 平衡 size

功能:插入,删除,根据数值查排名,根据排名查数据,找前驱后继

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

  1. 插入数值 x。

  2. 删除数值 x(若有多个相同的数,应只删除一个)。

  3. 查询数值 x 的排名(若有多个相同的数,应输出最小的排名)。

  4. 查询排名为 x 的数值。

  5. 求数值 x 的前驱(前驱定义为小于 x 的最大的数)。

  6. 求数值 x 的后继(后继定义为大于 x 的最小的数)。

注意: 数据保证查询的结果一定存在。


输入格式


第一行为 n,表示操作的个数。

接下来 n 行每行有两个数 opt 和 x,opt 表示操作的序号(1≤opt≤6)。


输出格式


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


#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
const int INF=1e8;
int n,m;
int root,idx;
struct node
{
	int l,r;
	int cnt,size;
	int key,val;
}t[N];

void pushup(int p)
{
	t[p].size=t[t[p].l].size+t[t[p].r].size+t[p].cnt;
}
void zig(int &p)
{
	int q=t[p].l;
	t[p].l=t[q].r;
	t[q].r=p;p=q;
	pushup(t[p].r);
	pushup(p);
}
void zag(int &p)
{
	int q=t[p].r;
	t[p].r=t[q].l;
	t[q].l=p;p=q;
	pushup(t[p].l);
	pushup(p);
}
int get_node(int key)
{
	t[++idx].key=key;
	t[idx].val=rand();
	t[idx].size=t[idx].cnt=1;
	return idx;
}
void build()
{
	get_node(-INF);get_node(INF);
	root=1;
	t[1].r=2;
	if(t[1].val<t[2].val) zag(root);
	pushup(root);
}
void insert(int &p,int key)
{
	if(!p) p=get_node(key);
	else if(t[p].key==key) t[p].cnt++;
	else if(t[p].key>key)
	{
		insert(t[p].l,key);
		if(t[t[p].l].val>t[p].val) zig(p);
	}
	else
	{
		insert(t[p].r,key);
		if(t[t[p].r].val>t[p].val) zag(p);
	}
	pushup(p);
}
void remove(int &p,int key)
{
	if(!p) return;
	if(t[p].key==key)
	{
		if(t[p].cnt>1) t[p].cnt--;
		else if(t[p].l||t[p].r)
		{
			if(!t[p].r||t[t[p].l].val>t[t[p].r].val)
			{
				zig(p);
				remove(t[p].r,key);
			}
			else
			{
				zag(p);
				remove(t[p].l,key);
			}
		}
		else p=0;
	}
	else if(t[p].key>key) remove(t[p].l,key);
	else remove(t[p].r,key);
	pushup(p);
}
int get_key_by_rank(int p,int rank)
{
	if(!p) return 0;
	if(t[t[p].l].size>=rank) return get_key_by_rank(t[p].l,rank);
	if(t[t[p].l].size+t[p].cnt>=rank) return t[p].key;
	return get_key_by_rank(t[p].r,rank-t[t[p].l].size-t[p].cnt);
}
int get_rank_by_key(int p,int key)
{
	if(!p) return INF;
	if(t[p].key==key) return t[t[p].l].size+1;
	if(t[p].key>key) return get_rank_by_key(t[p].l,key);
	return t[t[p].l].size+t[p].cnt+get_rank_by_key(t[p].r,key);
}
int get_prev(int p,int key)
{
	if(!p) return -INF;
	if(t[p].key>=key) return get_prev(t[p].l,key);
	return max(t[p].key,get_prev(t[p].r,key));
}
int get_next(int p,int key)
{
	if(!p) return INF;
	if(t[p].key<=key) return get_next(t[p].r,key);
	return min(t[p].key,get_next(t[p].l,key));
}


int main(){
	
	build();
    scanf("%d", &n);
    while (n -- )
    {
        int opt, x;
        scanf("%d%d", &opt, &x);
        if (opt == 1) insert(root, x);
        else if (opt == 2) remove(root, x);
        else if (opt == 3) printf("%d\n", get_rank_by_key(root, x) - 1);
        else if (opt == 4) printf("%d\n", get_key_by_rank(root, x + 1));
        else if (opt == 5) printf("%d\n", get_prev(root, x));
        else printf("%d\n", get_next(root, x));
    }

	
	
	return 0;
}

标签:return,get,int,rank,key,平衡,size
From: https://www.cnblogs.com/mrkou/p/16759032.html

相关文章

  • 平衡二叉树板子(转载)
    #include<iostream>#include<cstdio>#defineMAXN100010usingnamespacestd;introot,tot;structSplay{intfa;intch[2];intval;intcn......
  • 树结构系列(二):平衡二叉树、AVL树、红黑树
    前面说到二叉树在极端情况下会退化成链表,那如何解决这个问题呢?答案是:树的平衡。我们通过树的平衡,使得左右子树的深度保持在较小范围内,从而保证二叉树的查询效率。这就是平......
  • [答疑]当B中的合同额已定,A需求做得越多,这中间怎么平衡呢
    ​​软件方法(下)分析和设计第8章分析之分析类图——知识篇(20211227更新)​​​​软件方法(下)分析和设计第9章分析之分析类图——案例篇(20211228更新)​​问题时间:2013/11/25......
  • bzoj3612平衡
    题意:给定有\(2*n+1\)个刻度的尺子,再中间位置有一个支撑点,这样就成了一个跷跷板,每个刻度位置放一个砝码,所以跷跷板平衡。问拿走\(k\)个砝码仍然平衡的方案数。\(T\)组数据......
  • 【学习笔记】fhq_treap 无旋平衡树
    推一个视频引入Treap平衡树原型:基于旋转实现的BST+Heap,通过随机索引和堆使得BST的单次复杂度稳定在\(O(\logn)\)。fhqtreap则是将treap改造了一下,变成了基于分裂与......
  • AcWing 算法提高课 treap平衡树
    1、基本性质tree+heap=treap平衡树包含treap红黑树splaysbtAVL等等splay比较常用treap=①BST二叉搜索树+②heap2、set不能做的操作  ⑤和⑥这种与排名相......
  • 平衡二叉树(AVL)的插入和删除
    在计算机科学中,AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为1,所以它也被称为高度平衡树。查找、插入和删除在平均和最坏情况下都是......
  • 平衡树学习笔记
    平衡树平衡树是一类二叉查找树,因为普通的二叉查找树可能会因为特殊的数据的构造变成链,导致原本应该是\(\mathcalO(\logn)\)的查找速度退化成为\(\mathcalO(n)\),损失......
  • 平衡二叉树 -java实现
     packagetree;/***@author:tianhaichao*@date:2022/9/2215:38*@description:平衡二叉树AVL*1、每个节点的左右子树的高度差不大于1--->|left.height......
  • 【学习笔记】平衡树 Treap
    平衡树旋转Treap一个重要的等式treap=tree+heap解释:treap,即树堆,顾名思义,就是树+堆,而一般的,此处的树指BST(二叉搜索树)也就是说,treap是一棵BST,也是一个二叉堆,但二者的......