洛谷P3377 【模板】左偏树(可并堆)
设
dpi
d
p
i
为点
i
i
的子树中深度最大的点的深度,则左偏树满足性质,因此我们在合并两棵左偏树
x,y
x
,
y
(
x
x
应该在上方)的时候,就递归地将
x
x
的右儿子和合并,这样可以快速达到空节点.
struct leftist_tree
{
LL merge(LL a,LL b)
{
if (!a || !b) return a+b;
if (tr[a]>tr[b]) swap(a,b);//a在b上方
rson(a)=merge(rson(a),b);
tr[rson(a)].f=a;
if (tr[lson(a)].dp<tr[rson(a)].dp) swap(lson(a),rson(a));//维护左偏性质
tr[a].dp=tr[rson(a)].dp+1;//更新dp值
return a;
}
LL gf(LL x)
{
while (tr[x].f) x=tr[x].f;
return x;
}
void del(LL x)
{
tr[lson(x)].f=tr[rson(x)].f=0;
merge(lson(x),rson(x));
tr[x]=data();
}
LL ask(LL x)
{
if (!tr[x].id) return -1;
LL f=gf(x);
LL res=tr[f].key;
del(f);
return res;
}
}lt;