資料結構--左偏樹
阿新 • • 發佈:2021-09-22
左偏樹,顧名思義是左偏的,且保留堆的性質
至於為什麼它合併這麼快,因為它將右節點“空了出來”,便於新的左偏樹合併進來
左偏樹的一些性質就不說了,網上都有
重要的是打程式碼
首先要保證向右子樹合併
合併完要比較左右子樹的距離,如果左邊小於右邊,那就交換,保持左偏性質
最後更新根節點的距離=右節點的距離+1
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=100010; int n,m,opt,x,y; int lc[maxn],rc[maxn],dist[maxn],rt[maxn];View Codebool tf[maxn]; struct node { int v;int id; bool operator<(node x)const{return v==x.v?id<x.id:v<x.v;} }t[maxn<<1]; int find(int x){return rt[x]==x?x:rt[x]=find(rt[x]);} int merge(int x,int y) { if(!x||!y)return x+y; if(t[y]<t[x])swap(x,y); rc[x]=merge(rc[x],y);if(dist[lc[x]]<dist[rc[x]])swap(lc[x],rc[x]); dist[x]=dist[rc[x]]+1; return x; } int main() { dist[0]=-1; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&t[i].v),rt[i]=i,t[i].id=i; while(m--) { scanf("%d%d",&opt,&x); if(opt==1) { scanf("%d",&y); if(tf[x]||tf[y])continue; x=find(x);y=find(y); if(x!=y)rt[x]=rt[y]=merge(x,y); } if(opt==2) { if(tf[x]){printf("-1\n");continue;} x=find(x); printf("%d\n",t[x].v); tf[x]=true; rt[lc[x]]=rt[rc[x]]=rt[x]=merge(lc[x],rc[x]); lc[x]=rc[x]=dist[x]=0; } } return 0; }