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]--。递归结束后,可重构节点要重构。
C++
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);}