左偏树 模板

[介绍]左偏树是一个堆,并向左歪。
[Facts]

  • 外节点为没有左或右儿子的点
  • dis[x]为x到最近外节点距离
  • dis[0]=-1,0表示空节点
  • 左偏性:dis[左二子]>=dis[右儿子]
  • dis[x]=dis[右儿子]+1
    [code]https://www.luogu.com.cn/problem/P3377
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m;
int a[N],fa[N],ls[N],rs[N],dis[N],bk[N];
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
int merge(int x,int y){
	if(!x||!y)return x+y;
	if(a[x]>a[y]||a[x]==a[y]&&x>y)swap(x,y);
	rs[x]=merge(rs[x],y);
	if(dis[ls[x]]<dis[rs[x]])swap(ls[x],rs[x]);
	dis[x]=dis[rs[x]]+1;
	return x;
}
int main(){
	dis[0]=-1;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]),fa[i]=i;
	int op,x,y;
	while(m--){
		scanf("%d%d",&op,&x);
		if(op==1){scanf("%d",&y);if(bk[x]||bk[y])continue;x=find(x),y=find(y);if(x!=y)fa[x]=fa[y]=merge(x,y);}
		else{if(bk[x])puts("-1");else bk[y=find(x)]=1,cout<<a[y]<<'\n',fa[ls[y]]=fa[rs[y]]=fa[y]=merge(ls[y],rs[y]);}
	}
}
posted @ 2022-01-03 16:03  pengyule  阅读(23)  评论(0)    收藏  举报