悬赏一关注!萌新20pts平衡树求调QAQ
查看原帖
悬赏一关注!萌新20pts平衡树求调QAQ
546936
Ming_Yu楼主2023/1/30 13:40
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,ans,tot,rt;
struct p
{
	int val,cnt,rnd,l,r,size;
} b[N];
void push_up(int p)
{
	b[p].size=b[b[p].l].size+b[b[p].r].size+b[p].cnt;// 以p为根的树的大小
}
void zag(int &p)//左旋
{
	int q=b[p].r;//新节点
	b[p].r=b[q].l;
	b[q].l=p;
	b[q].size=b[p].size;
	push_up(p);
	p=q;
}
void zig(int &p)//右旋
{
	int q=b[p].l;//新节点
	b[p].l=b[q].r;
	b[q].r=p;
	b[q].size=b[p].size;
	push_up(p);
	p=q;
}
void insert(int &k,int p)
{
	if(!k)
	{
		tot++;
		k=tot;
		b[k].val=p;
		b[k].rnd=rand();
		b[k].size++;
		b[k].cnt++;
	}//没有相同的点,新建节点
	else if(b[k].val==p)
		b[k].cnt++;
	else if(b[k].val<p)
	{
		insert(b[k].r,p);//递归搜索,向右子树
		if(b[k].rnd>b[b[k].r].rnd)zag(k);
	}
	else
	{
		insert(b[k].l,p);//递归搜索,向右子树
		if(b[k].rnd>b[b[k].l].rnd)zig(k);
	}
	push_up(k);
}
bool del(int k,int p)
{
	if(!k)return false;
	if(b[k].val==p)
	{

		if(b[k].cnt>1)
		{
			b[k].cnt--;    //有多个点,删去一个即可
			b[k].size--;
			return true;
		}
		else
		{
			if(!b[k].l||!b[k].r)
			{
				k=b[k].l+b[k].r;
				return true;
			}			//叶子节点或者一个子节点,直接用子节点替代
			else//两个子节点
			{
				if(b[b[k].l].rnd<b[b[k].l].rnd)
				{
					zig(k);
					return del(k,p);
				}
				else
				{
					zag(k);
					return del(k,p);
				}
			}
		}
	}
	//继续递归搜索
	else if(b[k].val<p)
	{
		bool flg=del(b[k].r,p);
		if(flg)b[k].size--;
		return flg;
	}
	else
	{
		bool flg=del(b[k].l,p);
		if(flg)b[k].size--;
		return flg;
	}
//	push_up(k);
}
int rnk(int k,int p)
{
	if(!k)return 0;
	if(b[k].val==p)
		return b[b[k].l].size+1;
	else if(p>b[k].val)
		return b[b[k].l].size+b[k].cnt+rnk(b[k].r,p);
	else
		return rnk(b[k].l,p);
}
int num(int k,int rk)
{
	if(!k)return 0;
	if(rk<=b[b[k].l].size)return num(b[k].l,rk);//向左
	else if(rk>b[k].cnt+b[b[k].r].size)return num(b[k].r,rk-b[k].size-b[b[k].l].size);
	else return b[k].val;
}
void pre(int k,int p)
{
	if(!k)return;
	if(b[k].val<p)
		ans=k,pre(b[k].r,p);
	else
		pre(b[k].l,p);
}
void nxt(int k,int p)
{
	if(!k)return;
	if(b[k].val>p)
		ans=k,nxt(b[k].l,p);
	else
		nxt(b[k].r,p);
}
int main()
{
	scanf("%d",&n);
	int opt,x;
	for(int i=1; i<=n; i++)
	{
		scanf("%d%d",&opt,&x);
		if(opt==1)
			insert(rt,x);
		else if(opt==2)
			del(rt,x);
		else if(opt==3)
			printf("%d\n",rnk(rt,x));
		else if(opt==4)
			printf("%d\n",num(rt,x));
		else if(opt==5)
		{
			ans=0;
			pre(rt,x);
			printf("%d\n",b[ans].val);
		}
		else if(opt==6)
		{
			ans=0;
			nxt(rt,x);
			printf("%d\n",b[ans].val);
		}
	}
	return 0;
}
2023/1/30 13:40
加载中...