【XSY1986】【BZOJ1455】罗马游戏

就是一模板题。

合并就直接merge。

pop就是将自己的值设为一,再将自己的左右儿子合并即可。

查询直接找到堆顶,输出。

模板左偏树

代码:

#include<bits/stdc++.h>
using namespace std;
int dis[1000001],ch[1000001][2],fa[1000001],n,m,x,y,xx,yy,val[1000001];
char op[2];
int merge(int x,int y)
{
	if(!x||!y)
	{
		return x+y;
	}
	if(val[x]>val[y]||(val[x]==val[y]&&x>y))
	{
		swap(x,y);
	}
	ch[x][1]=merge(ch[x][1],y);
	if(dis[ch[x][0]]<dis[ch[x][1]])
	{
		swap(ch[x][0],ch[x][1]);
	}
	fa[x]=fa[ch[x][0]]=fa[ch[x][1]]=x;
	dis[x]=dis[ch[x][1]]+1;
	return x;
}
int getfa(int x)
{
	if(x!=fa[x])
	{
		return fa[x]=getfa(fa[x]);
	}
	return x;
}
void pop(int x)
{
	val[x]=-1;
	fa[ch[x][0]]=ch[x][0];
	fa[ch[x][1]]=ch[x][1];
	fa[x]=merge(ch[x][0],ch[x][1]);
}
int main()
{
	scanf("%d",&n);
	dis[0]=-1;
	for(int i=1;i<=n;i++)
	{
		fa[i]=i;
		scanf("%d",&val[i]);
	}
	scanf("%d",&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%s%d",op,&x);
		if(op[0]=='M')
		{
			scanf("%d",&y);
			if(x==y||val[x]==-1||val[y]==-1)
			{
				continue;
			}
			xx=getfa(x);
			yy=getfa(y);
			if(xx!=yy)
			{
				fa[xx]=fa[yy]=merge(xx,yy);
			}
		}else{
			if(val[x]==-1)
			{
				puts("0");
			}else{
				xx=getfa(x);
				printf("%d\n",val[xx]);
				pop(xx);
			}
		}
	}
	return 0;
}
posted @ 2019-08-19 16:20  ezoi_ly  阅读(117)  评论(0编辑  收藏  举报