左偏树 模板
[介绍]左偏树是一个堆,并向左歪。
[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]);}
}
}