社区讨论

抄蓝书的Treap93求调

P3369【模板】普通平衡树参与者 3已保存回复 7

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
7 条
当前快照
1 份
快照标识符
@lo13sqc2
此快照首次捕获于
2023/10/22 14:44
2 年前
此快照最后确认于
2023/11/02 14:15
2 年前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
struct Treap
{
	int l,r;
	int val,dat;
	int cnt,size;
};
int n,op,x,tot,root,Inf=0x7fffffff;
struct Treap a[100001];
int New(int val)
{
	++tot;
	a[tot].val=val;
	a[tot].dat=rand();
	a[tot].cnt=1;
	a[tot].size=1;
	return(tot);
}
void Update(int p)
{
	int lson=a[a[p].l].size;
	int rson=a[a[p].r].size;
	a[p].size=lson+rson+a[p].cnt;
}
void Build()
{
	New(-Inf);
	New(Inf);
	root=1;
	a[1].r=2;
	Update(root);
}
void zig(int &p)
{
	int q=a[p].l;
	a[p].l=a[q].r;
	a[q].r=p;
	p=q;
	Update(a[p].r);
	Update(p);
}
void zag(int &p)
{
	int q=a[p].r;
	a[p].r=a[q].l;
	a[q].l=p;
	p=q;
	Update(a[p].l);
	Update(p);
}
void Insert(int &p,int val)
{
	if(p==0)
	{
		p=New(val);
		return;
	}
	if(val==a[p].val)
	{
		++a[p].cnt;
		Update(p);
		return;
	}
	if(val<a[p].val)
	{
		Insert(a[p].l,val);
		if(a[p].dat<a[a[p].l].dat)
			zig(p);
	}else
	{
		Insert(a[p].r,val);
		if(a[p].dat<a[a[p].r].dat)
			zag(p);
	}
	Update(p);
}
void Remove(int &p,int val)
{
	if(p==0)
		return;
	if(val==a[p].val)
	{
		if(a[p].cnt>1)
		{
			--a[p].cnt;
			Update(p);
			return;
		}
		if(a[p].l||a[p].r)
		{
			if(a[p].r==0||a[a[p].l].dat>a[a[p].r].dat)
			{
				zig(p);
				Remove(a[p].r,val);
			}else
			{
				zag(p);
				Remove(a[p].l,val);
			}
			Update(p);
		}else
			p=0;
		return;
	}
	if(val<a[p].val)
		Remove(a[p].l,val);else
		Remove(a[p].r,val);
	Update(p);
}
int GetRankByVal(int p,int val)
{
	if(p==0)
		return(0);
	if(val==a[p].val)
		return(a[a[p].l].size+1);
	if(val<a[p].val)
		return(GetRankByVal(a[p].l,val));
	return(GetRankByVal(a[p].r,val)+a[a[p].l].size+a[p].cnt);
}
int GetValByRank(int p,int rank)
{
	if(p==0)
		return(Inf);
	if(a[a[p].l].size>=rank)
		return(GetValByRank(a[p].l,rank));
	if(a[a[p].l].size+a[p].cnt>=rank)
		return(a[p].val);
	return(GetValByRank(a[p].r,rank-a[a[p].l].size-a[p].cnt));
}
int GetPre(int val)
{
	int ans=1;
	int p=root;
	while(p)
	{
		if(val==a[p].val)
		{
			if(a[p].l>0)
			{
				p=a[p].l;
				while(a[p].r>0)
					p=a[p].r;
				ans=p;
			}
			break;
		}
		if(a[p].val<val&&a[p].val>a[ans].val)
			ans=p;
		p=val<a[p].val?a[p].l:a[p].r;
	}
	return(a[ans].val);
}
int GetNext(int val)
{
	int ans=2;
	int p=root;
	while(p)
	{
		if(val==a[p].val)
		{
			if(a[p].r>0)
			{
				p=a[p].r;
				while(a[p].l>0)
					p=a[p].l;
				ans=p;
			}
			break;
		}
		if(a[p].val>val&&a[p].val<a[ans].val)
			ans=p;
		p=val<a[p].val?a[p].l:a[p].r;
	}
	return(a[ans].val);
}
int main()
{
	Build();
	scanf("%d",&n);
	for(int i=1;i<=n;++i)
	{
		scanf("%d%d",&op,&x);
		switch(op)
		{
			case 1:
				Insert(root,x);
				break;
			case 2:
				Remove(root,x);
				break;
			case 3:
				printf("%d\n",GetRankByVal(root,x)-1);
				break;
			case 4:
				printf("%d\n",GetValByRank(root,x+1));
				break;
			case 5:
				printf("%d\n",GetPre(x));
				break;
			case 6:
				printf("%d\n",GetNext(x));
				break;
		}
	}
	return 0;
}

回复

7 条回复,欢迎继续交流。

正在加载回复...