【模板】左偏樹(可並堆) 可並堆_並查集
阿新 • • 發佈:2019-02-06
open nbsp amp pop set main freopen fin input
左偏樹的樹高是 $log(n)$ 級別的,所以在查詢祖先的時候是不可以直接順著左偏樹上的父親查詢的.
另開一個並查集,在並查集上進行路徑壓縮的查詢即可.
Code:
#include <cstdio> #include <algorithm> #include <cstring> #define maxn 100006 #define setIO(s) freopen(s".in","r",stdin) using namespace std; int n,m; struct MHEAP{ int f[maxn],ch[maxn][2],val[maxn],dis[maxn]; int merge(int x,int y){ if(!x||!y) return x+y; if(val[x]>val[y]||(val[x]==val[y]&&y<x)) swap(x,y); ch[x][1]=merge(ch[x][1],y); f[ch[x][1]]=f[ch[x][0]]=x; if(dis[ch[x][0]]<dis[ch[x][1]]) swap(ch[x][1],ch[x][0]); dis[x]=dis[ch[x][1]]+1; return x; } int getfa(int x) { return f[x]!=x ? f[x]=getfa(f[x]) : x; } void pop(int x) { f[ch[x][0]]=ch[x][0],f[ch[x][1]]=ch[x][1]; f[x]=merge(ch[x][0],ch[x][1]); val[x]=-1; } void opt1(int x,int y) { if(val[x]==-1||val[y]==-1) return; if(x==y) return ; int a=getfa(x),b=getfa(y); if(a==b) return ; merge(a,b); } void opt2(int x) { if(val[x]==-1) { printf("-1\n"); return; } int a=getfa(x); printf("%d\n",val[a]); pop(a); } }T; int main(){ //setIO("input"); scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) scanf("%d",&T.val[i]); for(int i=1;i<=n;++i) T.f[i]=i; for(int i=1,opt,a,b;i<=m;++i){ scanf("%d",&opt); if(opt==1) scanf("%d%d",&a,&b),T.opt1(a,b); if(opt==2) scanf("%d",&a),T.opt2(a); } return 0; }
【模板】左偏樹(可並堆) 可並堆_並查集