P3377-[模板]左偏树(可并堆)

正题

题目链接:https://www.luogu.com.cn/problem/P3377


题目大意

开始时 n n 个只有一个数的集合,要求支持

  1. 合并两个集合
  2. 查询一个集合中的最小值并删除

c o d e code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+10;
int n,m,val[N];
struct Left_tree{
	int dis[N],fa[N],t[N][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);
		int &ls=t[x][0],&rs=t[x][1];
		rs=Merge(rs,y);
		if(dis[ls]<dis[rs]) swap(ls,rs);
		fa[rs]=fa[ls]=x;
		dis[x]=dis[rs]+1;
		return x;
	}
	void Del(int x){
		int ls=t[x][0],rs=t[x][1];
		fa[ls]=ls;fa[rs]=rs;val[x]=-1;
		fa[x]=Merge(ls,rs);
	}
	int Get(int x)
	{return (fa[x]==x)?(x):(fa[x]=Get(fa[x]));}
}T;
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%d",&val[i]),T.fa[i]=i;
	while(m--){
		int op,x,y;
		scanf("%d%d",&op,&x);
		if(op==1){
			scanf("%d",&y);
			if(val[x]==-1||val[y]==-1)
				continue;
			x=T.Get(x);y=T.Get(y);
			T.Merge(x,y);
		}
		if(op==2){
			if(val[x]==-1){printf("-1\n");continue;}
			x=T.Get(x);printf("%d\n",val[x]);T.Del(x);
		}
	}
}
发布了867 篇原创文章 · 获赞 55 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/Mr_wuyongcong/article/details/104053612