「學習筆記」左偏樹
阿新 • • 發佈:2021-07-01
//合併 int merge(int x,int y){ if(!x || !y) return x|y; if(t[x].key>t[y].key) swap(x,y); t[t[x].rs=merge(t[x].rs,y)].fa=x; if(t[t[x].rs].d>t[t[x].ls].d) swap(t[x].ls,t[x].rs); t[x].d=t[t[x].rs].d+1; return x; } //構建 void build(){ int l=1,r=n; for(int i=1;i<n;i++){//可證只有n-1次合併 h[++r]=merge(h[l],h[l+1]); l+=2; } } //刪除任意結點(pop) void pushup(int x){ if(!x) return; if(t[x].d!=t[t[x].rs].d+1){ t[x].d=t[t[x].rs].d+1; pushup(t[x].fa); } } int merge(int x,int y){ if(!x || !y) return x|y; if(t[x].key>t[y].key) swap(x,y); t[t[x].rs=merge(t[x].rs,y)].fa=x; if(t[t[x].rs].d>t[t[x].ls].d) swap(t[x].ls,t[x].rs); pushup(x); return x; } int pop(int x){ return merge(t[x].ls,t[x].rs); } //整個堆加/減去一個值、乘上一個正數,在根上打標記,下傳 int merge(int x,int y){ if(!x || !y) return x|y; if(t[x].key>t[y].key) swap(x,y); pushdown(x); t[t[x].rs=merge(t[x].rs,y)].fa=x; if(t[t[x].rs].d>t[t[x].ls].d) swap(t[x].ls,t[x].rs); pushup(x); return x; } int pop(int x){ pushdown(x); return merge(t[x].ls,t[x].rs); } //隨機合併 int merge(int x,int y){ if(!x || !y) return x|y; if(t[x].key>t[y].key) swap(x,y); if(rand()&1) swap(t[x].ls,t[x].rs); t[x].ls=merge(t[x].ls,y); return x; } //最終的板子 void pushup(int x){ if(!x) return; if(t[x].d!=t[t[x].rs].d+1){ t[x].d=t[t[x].rs].d+1; pushup(t[x].fa); } } int merge(int x,int y){ if(!x || !y) return x|y; if(t[x].key>t[y].key) swap(x,y); pushdown(x); t[t[x].rs=merge(t[x].rs,y)].fa=x; if(t[t[x].rs].d>t[t[x].ls].d) swap(t[x].ls,t[x].rs); pushup(x); return x; } int pop(int x){ pushdown(x); return merge(t[x].ls,t[x].rs); }