luogu P3377 【模板】左偏树(可并堆)

这个在我讲左偏树的模板里写的很清楚了,直接上个代码吧:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

const int N=100009;
int lc[N],rc[N],fa[N],n,m,d[N],del[N];
struct V
{
	int id,val;
	bool operator < (const V &A)const
	{
		return val!=A.val?val<A.val:id<A.id;
	}
}a[N];

int merge(int x,int y)
{
	if(!x||!y)
		return x+y;
	if(a[y]<a[x])
		swap(x,y);
	rc[x]=merge(rc[x],y);
	if(d[lc[x]]<d[rc[x]])
		swap(lc[x],rc[x]);
	d[x]=d[rc[x]]+1;
	return x;
}

int find(int x)
{
	return fa[x]==x?x:fa[x]=find(fa[x]);
}

void init()
{
	scanf("%d %d",&n,&m);
	for (int i=1;i<=n;i++)
		scanf("%d",&a[i].val),a[i].id=i,fa[i]=i;
}

void work()
{
	for (int _=1;_<=m;_++)
	{
		int opt,x,y;
		scanf("%d",&opt);
		if(opt==1)
		{
			scanf("%d %d",&x,&y);
			if(del[x]||del[y])
				continue;
			x=find(x),y=find(y);
			if(x!=y)
				fa[x]=fa[y]=merge(x,y);
		}
		else
		{
			scanf("%d",&x);
			if(del[x])
			{
				puts("-1");
				continue;
			}
			x=find(x);
			printf("%d\n",a[x].val),del[x]=1;
			fa[rc[x]]=fa[lc[x]]=fa[x]=merge(lc[x],rc[x]);
		}
	}
}

int main()
{
	init();
	work();
	return 0;
}
posted @ 2020-05-02 16:39  With_penguin  阅读(107)  评论(0编辑  收藏  举报