Treap求助 悬赏 1 关注
  • 板块学术版
  • 楼主zn_qq_he
  • 当前回复3
  • 已保存回复3
  • 发布时间2023/6/17 14:21
  • 上次更新2023/10/23 12:57:36
查看原帖
Treap求助 悬赏 1 关注
705385
zn_qq_he楼主2023/6/17 14:21

rt 已经知道是左旋右旋的问题,但不知道怎么调

#include<bits/stdc++.h>
using namespace std;
struct node
{
	int size;
	int rs;
	int ls;
	int v;
	int p;
};
node tree[100010];
int tot,root;
void zs(int pos)
{
	tree[pos].size=tree[tree[pos].ls].size+tree[tree[pos].rs].size+1;
	return;
}
void lturn(int &pos)
{
	node x=tree[tree[pos].rs];
	tree[pos].rs=x.ls;
	x.ls=pos;
	x.size=tree[pos].size;
	zs(pos);
	tree[pos]=x;
	return;
}
void rturn(int &pos)
{
	node x=tree[tree[pos].ls];
	tree[pos].ls=x.rs;
	x.rs=pos;
	x.size=tree[pos].size;
	zs(pos);
	tree[pos]=x;
	return;
}
void insert(int &pos,int x)
{
	if(!pos)
	{
		pos=++tot;
		tree[pos].v=x;
		tree[pos].p=rand();
		tree[pos].size=1;
		return;
	}
	if(x<tree[pos].v)
	{
		insert(tree[pos].ls,x);
		if(tree[pos].p<tree[tree[pos].ls].p)
			rturn(pos);
	}
	else
	{
		insert(tree[pos].rs,x);
			if(tree[pos].p<tree[tree[pos].rs].p)
				lturn(pos);
	}
	zs(pos);
	return ;
}
void remove(int pos,int x)
{
	if(!pos)
		return;
	if(tree[pos].v==x)
	{
		if(tree[pos].ls|tree[pos].rs)
		{
			if(tree[tree[pos].ls].p>tree[tree[pos].rs].p)
			{
				rturn(pos);
				remove(tree[pos].rs,x);
			}
			else
			{
				lturn(pos);
				remove(tree[pos].ls,x);
			}
		}
		else
			pos=0;
	}
	else
	{
		if(x<tree[pos].v)
			remove(tree[pos].ls,x);
		else	
			remove(tree[pos].rs,x);
	}
	if(pos)
		zs(pos);
}
int ranknum(int pos,int x)
{
	if(!pos)
		return 1;
	if(x<tree[pos].v)
		return ranknum(tree[pos].ls,x);
	else
		return ranknum(tree[pos].rs,x)+tree[tree[pos].ls].size+1;
}
int numrank(int pos,int x)
{
	int k=tree[tree[pos].ls].size;
	if(x==k+1)
		return tree[pos].v;
	else if(x<=k)
		return numrank(tree[pos].ls,x);
	else 
		return numrank(tree[pos].rs,x-k-1);
}
int prev(int pos,int x)
{
	if(!pos)
		return -1000000000;
	if(x<tree[pos].v)
		return prev(tree[pos].ls,x);
	else
		return max(tree[pos].v,prev(tree[pos].rs,x));
}
int nxt(int pos,int x)
{
	if(!pos)
		return 1000000000;
	if(x>=tree[pos].v)
		return nxt(tree[pos].rs,x);
	else
		return min(tree[pos].v,nxt(tree[pos].ls,x));
}
int main()
{
	int n,ox,op;
	scanf("%d",&n);
	while(n--)
	{
		scanf("%d%d",&op,&ox);
		if(op==1)
			insert(root,ox);
		if(op==2)
			remove(root,ox);
		if(op==3)
			printf("%d\n",ranknum(root,ox));
		if(op==4)
			printf("%d\n",numrank(root,ox));
		if(op==5)
			printf("%d\n",prev(root,ox));
		if(op==6)
			printf("%d\n",nxt(root,ox));
	}
	return 0;
}


2023/6/17 14:21
加载中...