标签:bsp oid inf code span EAP ++ -- 递归
利用rand保持堆的特性
const int N=; int ls[N],rs[N],v[N],p[N],cnt[N],siz[N]; // 权值 优先级 inline void update(int &k){ siz[k]=siz[ls[k]]+siz[rs[k]];} inline void zig(int &k){//treap旋转上实际上是在根节点,不记录fa int y=ls[k];// < 入 ls[k]=rs[y]; rs[y]=k; siz[y]=siz[k]; update(k); k=y;//令k返回根节点 } inline void zag(int &k){ int y=rs[k]; rs[y]=ls[y]; ls[y]=k; siz[y]=siz[k]; update(k); k=y; } inline void insert(int &k,int &val){ if(!k){ k=++idx;v[k]=val;p[k]=rand(); cnt[k]=siz[k]=1;return;} else ++siz[k]; if(val<v[k]){ insert(ls[k],val); if(p[ls[k]]<p[k]) zig(k);} else if(v[k]==val) ++cnt[k]; else{insert(rs[k],val); if(p[rs[k]]<p[k]) zag(k);} } inline void del(int &k,int &val){ //找到链节点或者数值>1即可直接不用再递归 if(val==v[k]){ if(1<cnt[k]) --cnt[k],--siz[k]; //数值>1 else if(!ls[k]||!rs[k]) k=ls[k]+rs[k]; //链结点 //两个非空节点 else if(p[ls[k]]<p[rs[k]]) zig(k),del(k,val); else zag(k),del(k,val); return; } --siz[k]; if(val<v[k]) del(ls[k],val); else del(rs[k],val); } //前驱后继 inline int pre(int &val){ int k=rt,ans=-inf; while(k){ if(v[k]<=val) ans=v[k],k=rs[k]; else k=ls[k];} return ans;} inline int beh(int &val){ int k=rt,ans=-inf; while(k){ if(val<=v[k]) ans=v[k],k=ls[k]; else k=rs[k];} return ans;} // inline int queryKth(int x){ int k=rt; while(k){ if(siz[ls[k]]<x&&x<=siz[ls[k]]+cnt[k]) return v[k]; if(x<=siz[ls[k]]) k=ls[k]; else k-=siz[ls[k]]+cnt[k],k=rs[k];} return 0; } inline int queryrank(int &val){ int k=rt,res=0; while(k){ if(v[k]==val) return res+siz[ls[k]]+1; else if(val<v[k]) k=ls[k]; else res+=siz[ls[k]]+cnt[k],k=rs[k];} return res; }
标签:bsp oid inf code span EAP ++ -- 递归
原文地址:https://www.cnblogs.com/asdic/p/9635377.html