标签:EAP hup sla lse cpp rand 表示 kth lan
\(split:\)将一棵\(Treap\)按照某种划分标准分成\(a\)和\(b\)两棵\(Treap\)
\(x\)和\(y\)分别表示\(a\)和\(b\)的根
划分后,\(a\)中所有元素都\(\leqslant k\),\(b\)中所有元素都\(>k\)
权值分裂
\(code:\)
void split(int p,int k,int &x,int &y)
{
if(!p)
{
x=y=0;
return;
}
if(val[p]<=k) x=p,split(rs[p],k,rs[p],y);
else y=p,split(ls[p],k,x,ls[p]);
pushup(p);
}
排名分裂
\(code:\)
void split(int p,int k,int &x,int &y)
{
if(!p)
{
x=y=0;
return;
}
if(siz[ls[p]]<k) x=p,split(rs[p],k-siz[ls[p]]-1,rs[p],y);
else y=p,split(ls[p],k,x,ls[p]);
pushup(p);
}
\(merge:\)合并\(x\)和\(y\),合并后的\(Treap\)的根为\(p\),因为先\(split\),所以\(x\)中所有元素都都小于\(y\)
\(code:\)
int add(int x)
{
val[++tot]=x;
siz[tot]=1;
key[tot]=rand();
return tot;
}
void pushup(int x)
{
siz[x]=siz[ls[x]]+siz[rs[x]]+1;
}
void merge(int &p,int x,int y)
{
if(!x||!y)
{
p=x+y;
return;
}
if(key[x]<key[y]) p=x,merge(rs[p],rs[p],y);
else p=y,merge(ls[p],x,ls[p]);
pushup(p);
}
void split(int p,int k,int &x,int &y)
{
if(!p)
{
x=y=0;
return;
}
if(val[p]<=k) x=p,split(rs[p],k,rs[p],y);
else y=p,split(ls[p],k,x,ls[p]);
pushup(p);
}
void insert(int v)
{
split(root,v,x,y);
merge(x,x,add(v));
merge(root,x,y);
}
void del(int v)
{
split(root,v,x,y);
split(x,v-1,x,z);
merge(z,ls[z],rs[z]);
merge(x,x,z);
merge(root,x,y);
}
int kth(int v)
{
split(root,v-1,x,y);
int ans=siz[x]+1;
merge(root,x,y);
return ans;
}
int get(int p,int k)
{
if(k==siz[ls[p]]+1) return val[p];
if(k<=siz[ls[p]]) return get(ls[p],k);
else return get(rs[p],k-siz[ls[p]]-1);
}
int pre(int v)
{
split(root,v-1,x,y);
int ans=get(x,siz[x]);
merge(root,x,y);
return ans;
}
int nxt(int v)
{
split(root,v,x,y);
int ans=get(y,1);
merge(root,x,y);
return ans;
}
标签:EAP hup sla lse cpp rand 表示 kth lan
原文地址:https://www.cnblogs.com/lhm-/p/12229556.html