voidIns(int&k,intp){// 在以 k 為根的子樹內添加權值為 p 節點if(!k){k=++cnt;if(!rt)rt=1;w[k]=p;lc[k]=rc[k]=0;wn[k]=s[k]=sz[k]=sd[k]=1;}else{if(w[k]==p)wn[k]++;elseif(w[k]<p)Ins(rc[k],p);elseIns(lc[k],p);Calc(k);if(CanRbu(k))Rbu(k);}}
刪除
惰性刪除,到達空結點則忽略,找到對應結點則 wn[k]--。遞歸結束後,可重構節點要重構。
1 2 3 4 5 6 7 8 91011121314151617
voidDel(int&k,intp){// 從以 k 為根子樹移除權值為 p 節點if(!k)return;else{if(w[k]==p){if(wn[k])wn[k]--;}else{if(w[k]<p)Del(rc[k],p);elseDel(lc[k],p);}Calc(k);if(CanRbu(k))Rbu(k);}}
intMyUprBd(intk,intp){// 在以 k 為根子樹中,大於 p 的最小數的名次if(!k)return1;elseif(w[k]==p&&wn[k])returnsz[lc[k]]+1+wn[k];elseif(p<w[k])returnMyUprBd(lc[k],p);elsereturnsz[lc[k]]+wn[k]+MyUprBd(rc[k],p);}
intMyAt(intk,intp){// 以 k 為根的子樹中,名次為 p 的權值if(!k)return0;elseif(sz[lc[k]]<p&&p<=sz[lc[k]]+wn[k])returnw[k];elseif(sz[lc[k]]+wn[k]<p)returnMyAt(rc[k],p-sz[lc[k]]-wn[k]);elsereturnMyAt(lc[k],p);}