合并操作
这是属于一个左偏树的基本操作了吧。。这里就不做解释了
时间
O(logn)
int Merge (int x,int y)
{
if (x==0) return y;
if (y==0) return x;
if (v[x]>v[y]) swap(x,y);//保证x可以做根
r[x]=Merge(r[x],y);
if (d[r[x]]>d[l[x]]) swap(r[x],l[x]);
d[x]=d[r[x]]+1;
return x;
}
插入操作
我们就把这个点当做一个独立的左偏树,然后用上面的方法合并就好了
时间
O(logn)
删除最大值操作
比如说我们要删除x这个节点
我们就将x的左右儿子合并成另一棵左偏树就好了
删除指定的一个节点
在05年上的论文有详细的解释,也是
O(logn)
的
但是我认为,我们并不需要这么左
我们只需要将被删掉的节点打一个标记
等我们访问到他的时候跳过就好了
我实在没想到什么方法可以卡这个
要是有人想到了,欢迎打脸
Update8.15
话说前几天我做了一个题,
bzoj3040
这里要用一个高效的堆来优化dij
要是你每次只是打标记的话,可能会使一个点在队列中的次数太多
也就是节点过多,而造成RE
因此,删除操作还是有用的
但是这种题估计很少吧
修改某一个节点的值
我觉得这个可以等同于两个操作:删除这个点,再加入这个点
方法见上面
取得最小/大值
分别维护大根和小跟的左偏树就可以了
到这里基本操作应该写完了吧。
要是还有新的再更。。。