2018-team4-modules-非旋Treap
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
{{{
#define L a[t].l
#define R a[t].r
#define F fa[t]
typedef pair<int,int> pii;
void get(int &x,int &y,pii t){x=t.first,y=t.second;}
//merge,返回值为合并后的根
//若其中一个为空树直接返回,否则递归
int mer(int x,int y){
return x==0||y==0?x+y:a[y].k>a[x].k?
(a[x].r=mer(a[x].r,y),up(x),x):
(a[y].l=mer(x,a[y].l),up(y),y);
}
//从上向下分裂,返回值为分裂后的两个根
pii spl(int t,int k){
if (!k) return pii(t,0);
if (k==a[t].sz) return pii(0,t);
int p=k-a[R].sz-1; return p>=0?
(get(p,L,spl(L,p)),up(t),pii(p,t)):
(get(R,p,spl(R,k)),up(t),pii(t,p));
}
//自下向上分裂,要多维护一个fa数组
//要多维护个fa数组,split的时候要清fa
pii spl(int t){
int l=L,r=R,tp=t;
for (;F;t=F) a[F].l==t?
r=fa[a[F].l=r]=F:
l=fa[a[F].r=l]=F;
t=tp,L=R=F=fa[l]=fa[r]=0;
return pii(l,r);
}
}}}
#define L a[t].l
#define R a[t].r
#define F fa[t]
typedef pair<int,int> pii;
void get(int &x,int &y,pii t){x=t.first,y=t.second;}
//merge,返回值为合并后的根
//若其中一个为空树直接返回,否则递归
int mer(int x,int y){
return x==0||y==0?x+y:a[y].k>a[x].k?
(a[x].r=mer(a[x].r,y),up(x),x):
(a[y].l=mer(x,a[y].l),up(y),y);
}
//从上向下分裂,返回值为分裂后的两个根
pii spl(int t,int k){
if (!k) return pii(t,0);
if (k==a[t].sz) return pii(0,t);
int p=k-a[R].sz-1; return p>=0?
(get(p,L,spl(L,p)),up(t),pii(p,t)):
(get(R,p,spl(R,k)),up(t),pii(t,p));
}
//自下向上分裂,要多维护一个fa数组
//要多维护个fa数组,split的时候要清fa
pii spl(int t){
int l=L,r=R,tp=t;
for (;F;t=F) a[F].l==t?
r=fa[a[F].l=r]=F:
l=fa[a[F].r=l]=F;
t=tp,L=R=F=fa[l]=fa[r]=0;
return pii(l,r);
}