一个写的不错的Splay模板

本文详细介绍了一种基于二叉搜索树的自平衡算法实现,包括插入、删除、查找等核心操作,以及如何通过旋转保持树的平衡,确保操作效率。文章深入探讨了自底向上和自顶向下的平衡策略,提供了丰富的代码示例。

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

#include<bits/stdc++.h>
#define N 100005
using namespace std;
struct Node{
	int ch[2],val,fa,size,cnt;
}t[N];
int root,tot,n,ans;
int read(){
    int cnt=0,f=1;char ch=0;
    while(!isdigit(ch)){ch=getchar();if(ch=='-')f=-1;}
    while(isdigit(ch))cnt=cnt*10+(ch-'0'),ch=getchar();
    return cnt*f;
}
void update_size(int x){
	t[x].size=t[t[x].ch[0]].size+t[t[x].ch[1]].size+t[x].cnt;
}
void rotate(int x){
	int y=t[x].fa,z=t[y].fa;
	int k=(t[y].ch[1]==x);
	t[z].ch[t[z].ch[1]==y]=x;
	t[x].fa=z;
	t[y].ch[k]=t[x].ch[k^1];
	t[t[x].ch[k^1]].fa=y;
	t[x].ch[k^1]=y;
	t[y].fa=x;
	update_size(y),update_size(x);
}
void splay(int x,int goal){
	if(x==0) return;
	while(t[x].fa!=goal){
		int y=t[x].fa,z=t[y].fa;
		if(z!=goal) 
			(t[y].ch[1]==x)^(t[z].ch[1]==y)?rotate(x):rotate(y);
		rotate(x);
	}if(goal==0) root=x;
}
void insert(int x){
	int o=root,fa=0;
	while(o&&t[o].val!=x){
		fa=o,o=t[o].ch[x>t[o].val];
	} 
	if(o) t[o].cnt++;
	else{
		o=++tot;
		if(fa) t[fa].ch[x>t[fa].val]=o;
		t[o].fa=fa,t[o].size=t[o].cnt=1,t[o].val=x;
	}
	splay(o,0);
}
void pre(int o,int x){
	if(o==0) return;
	if(t[o].val<x){
		ans=o,pre(t[o].ch[1],x);
	}else pre(t[o].ch[0],x);
}
void suf(int o,int x){
	if(o==0) return;
	if(t[o].val>x){
		ans=o,suf(t[o].ch[0],x);
	}else suf(t[o].ch[1],x);
}
void erase(int x){
	pre(root,x); int last=ans;
	suf(root,x); int next=ans;
	splay(last,0),splay(next,last);
	int del=t[next].ch[0];
	if(t[del].cnt>1) t[del].cnt--,splay(del,0);
	else t[next].ch[0]=0;
}
int rank_x(int o,int x){
	if(x<t[o].val) return rank_x(t[o].ch[0],x);
	else if(x>t[o].val) 
		return rank_x(t[o].ch[1],x)+t[t[o].ch[0]].size+t[o].cnt;
	else return t[t[o].ch[0]].size+1; 
}
int rank_k(int o,int k){
	if(t[t[o].ch[0]].size>=k) return rank_k(t[o].ch[0],k);
	else if(t[t[o].ch[0]].size+t[o].cnt<k) 
		return rank_k(t[o].ch[1],k-t[t[o].ch[0]].size-t[o].cnt);
	else return t[o].val;
}
int main(){
	n=read();
	insert(2147483647);
	insert(-2147483647);
	for(int i=1;i<=n;i++){
		int op=read(),x=read();
		if(op==1) insert(x);
		if(op==2) erase(x);
		if(op==3) printf("%d\n",rank_x(root,x)-1);
		if(op==4) printf("%d\n",rank_k(root,x+1));
		if(op==5) pre(root,x),printf("%d\n",t[ans].val);
		if(op==6) suf(root,x),printf("%d\n",t[ans].val);
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

FSYo

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

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

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

打赏作者

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

抵扣说明:

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

余额充值