左偏树+笛卡尔树
左偏树/可并堆
外部点:左儿子或右儿子为空的节点
\(dis_{x}\):距离 \(x\) 最近的外部点
性质:
- 小根堆
就是要维护这个的 - 距离为 \(n\) 的左偏树至少有 \(2^{n+1}-1\) 个节点
否则必然会有一个节点距离 \(<n\) - \(n\) 个点的左偏树树高为 \(log\)
维护保证了,结合上面理解。
后来周邦在课上拷打我了,这该怎么办呢?
我们发现 \(merge\) 是和 \(dis\) 相关的,所以就做完了
合并:
正常堆合并参考 fhq 的 \(merge\),随机选一个儿子合并,期望是 \(log\) 的
左偏树中左儿子距离>右儿子距离,那么将右儿子合并
然后挑一个 \(dis\) 小的儿子并上去
支持操作:
合并,删除最小数(合并左右子树),求最小值
int merg(int x,int y){
int xi=get(x),yi=get(y);
push_down(xi),push_down(yi);
return fa[xi]=fa[yi]=merge(xi,yi);
}
int del(int x){
x=get(x);
push_down(x);
return fa[x]=fa[son[x][0]]=fa[son[x][1]]=merge(son[x][0],son[x][1]);
}
笛卡尔树
我们的单调栈维护的是从根的右链,然后注意一下就可以了。
性质
你的脑子好像不是特别好
\(lca(l,r)\) 的值是 \([l,r]\) 的最大值。
考虑证明,首先 \(lca(l,r)\) 上面的点不可能成为最大值,因为 \(l,r\) 都在上面那个点的左边或者右边(根据按照下标的二叉搜索树的性质)然后 \(lca(l,r)\) 一定在 \(l\) 和 \(r\) 之间,怎么证明。很简单啊,\(l,r\)分别在 \(lca(l,r)\) 的左右两棵子树中

浙公网安备 33010602011771号