treap 普通平衡树

     普通treap中最普通的板子(数组版)

      

#include<stdio.h>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cmath>
#define inf 10000000
using namespace std;
struct tree
{
	int l,r,size,tot,h,rd;
} t[100005];
int n,root,fro,bac,hh;
void l_swap(int &root)
{
	int k=t[root].r;
	t[root].r=t[k].l;
	t[k].l=root;
	t[k].size=t[root].size;
	t[root].size=t[t[root].l].size+t[t[root].r].size+t[root].tot;
	root=k;
}
void r_swap(int &root)
{
	int k=t[root].l;
	t[root].l=t[k].r;
	t[k].r=root;
	t[k].size=t[root].size;
	t[root].size=t[t[root].l].size+t[t[root].r].size+t[root].tot;
	root=k;
}
void build(int &root,int k)
{
	if(!root)
	{
		root=++hh;
		t[root].h=k;
		t[root].size=t[root].tot=1;
		t[root].rd=rand();
		return;
	}
	t[root].size++;
	if(t[root].h==k)t[root].tot++;
	else
	{
		if(t[root].h>k)
		{
			build(t[root].l,k);
			if(t[t[root].l].rd<t[root].rd);
			   r_swap(root);
		}
		else
		{
			build(t[root].r,k);
			if(t[t[root].r].rd<t[root].rd)
			    l_swap(root);
		}
	}
}
void del(int &root,int k)
{
	if(!root)return;
	if(t[root].h==k)
	{
		if(t[root].tot>1)
		{
			t[root].tot--;
			t[root].size--;
			return;
		}
		if(t[root].l*t[root].r==0)
		    root=t[root].l+t[root].r;
		else
		{
			if(t[t[root].l].rd<t[t[root].r].rd)
			    r_swap(root);
			else
			    l_swap(root);
			del(root,k);
		}
	}
	else
	{
		 t[root].size--;
		 if(k>t[root].h)del(t[root].r,k);
		 else del(t[root].l,k);
	}
}
void FRO(int &root,int k)
{
	if(!root)return;
	if(t[root].h<k)
	{
		fro=t[root].h;
		FRO(t[root].r,k);
	}
	else FRO(t[root].l,k);
}
void BAC(int &root,int k)
{
	if(!root)return;
	if(t[root].h>k)
	{
		bac=t[root].h;
		BAC(t[root].l,k);
	}
	else BAC(t[root].r,k);
}
int num(int &root,int k)
{
	if(!root)return 0;
	if(t[root].h==k)
	    return t[t[root].l].size+1;
	else
	{
		if(t[root].h>k)return num(t[root].l,k);
		else  return t[t[root].l].size+t[root].tot+num(t[root].r,k);
	}
}
int Q(int &root,int k)
{
	if(!root)return 0;
	if(t[t[root].l].size+1<=k&&t[t[root].l].size+t[root].tot>=k)
	     return t[root].h;
	if(t[t[root].l].size>=k)
	     return Q(t[root].l,k);
	if(t[t[root].l].size<k)
	     return Q(t[root].r,k-t[root].tot-t[t[root].l].size);
}
int yjn()
{
//	 freopen("phs.in","r",stdin);
  //  freopen("phs.out","w",stdout);
	scanf("%d",&n);
	int x,y;
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&x,&y);
		if(x==1)build(root,y);
		if(x==2)del(root,y);
		if(x==3){printf("%d\n",num(root,y));}
		if(x==4){printf("%d\n",Q(root,y));}
		if(x==5){fro=-inf;FRO(root,y);printf("%d\n",fro);}
		if(x==6){bac=-inf;BAC(root,y);printf("%d\n",bac);}
	}
}
int qty=yjn();
int main(){;}

### Treap树的基本原理 Treap(Tree + Heap)是一种结合了二叉搜索树(BST)和堆(Heap)特性的数据结构。每个节点包含两个属性:一个用于满足二叉搜索树性质的关键值(key),以及一个用于满足堆性质的随机优先级(priority)。Treap通过维护这两个性质来实现高效的插入、删除和查找操作。 - **二叉搜索树性质**:对于任意节点,其左子树中的所有节点的关键值都小于该节点的关键值,而右子树中的所有节点的关键值都大于该节点的关键值。 - **堆性质**:每个节点的优先级都大于其子节点的优先级,这样可以确保树的高度在期望上是平衡的。 Treap的随机优先级设计使得树的结构在期望上接近于完全平衡的状态,从而保证了平均时间复杂度为 $O(\log n)$ 的操作性能 [^3]。 ### Treap的实现方式 Treap的实现主要包括插入、删除、查找等操作,其核心机制依赖于旋转操作和分裂/合并操作。 1. **插入操作**:插入一个新节点时,首先按照二叉搜索树的方式找到合适的位置。插入后,如果新节点的优先级大于其父节点的优先级,则通过旋转操作调整树的结构以维护堆性质。 2. **删除操作**:删除节点时,需要通过旋转操作将该节点“下沉”到叶子位置,然后直接删除。或者,可以将树分裂为两部分,删除目标节点后重新合并。 3. **查找操作**:查找操作与普通二叉搜索树相同,按照关键值进行比较并递归地在左子树或右子树中查找。 4. **分裂与合并操作**:分裂操作将树分成两部分,通常基于某个关键值或路径;合并操作则将两棵树合并为一棵,前提是它们的关键值范围不重叠 [^5]。 以下是Treap的基本插入操作的伪代码示例: ```python class TreapNode: def __init__(self, key, priority): self.key = key self.priority = priority self.left = None self.right = None def insert(root, key, priority): if root is None: return TreapNode(key, priority) elif key < root.key: root.left = insert(root.left, key, priority) if root.left.priority > root.priority: root = rotate_right(root) else: root.right = insert(root.right, key, priority) if root.right.priority > root.priority: root = rotate_left(root) return root def rotate_right(y): x = y.left T2 = x.right x.right = y y.left = T2 return x def rotate_left(x): y = x.right T2 = y.left y.left = x x.right = T2 return y ``` ### Treap的应用场景 Treap在实际应用中适用于以下场景: 1. **简化代码复杂度**:Treap的实现相对简单,尤其在不需要严格平衡的场景中,其插入和删除操作的常数因子较低,适合需要快速实现的项目 [^1]。 2. **动态数据集合**:当数据集合需要频繁插入和删除时,Treap的随机优先级设计可以有效地保持树的平衡,从而保证高效的查找性能。 3. **概率性平衡需求**:Treap的平衡性依赖于随机优先级,适用于对概率性平衡有一定容忍度的应用场景 [^2]。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值