本人用 treap 整了一个 O(玄学) 的方法,大致思路就是离线用高度排序,每次把询问高度以下的边相连的点的 treap 暴力合并,所以需要维护每个节点的父亲来找某个 treap 的根,这一过程使用了路径压缩。我交的第一发 MLE 了,理论上 treap 的高度是 logn 级别的,不可能爆空间,于是我把合并 treap 的函数重构了一些,只是把执行的顺序变了,原来是先合并子节点,再合并当前节点,改成了先合并当前节点,然后就过了,而且空间只有 17MB,远远没有超过空间。请问是什么原因?理论上 MLE 的递归最深时为 remake + merge 是两个 log。 MLE:
int remake(int a, int b){
if(!b) return a;
a = remake(a, tree[b].l);
a = remake(a, tree[b].r);
tree[tree[b].l].fa = tree[b].l;
tree[tree[b].r].fa = tree[b].r;
tree[b].l = tree[b].r = 0;
tree[b].siz = 1;
int x, y;
split1(a, tree[b].w, x, y);
return merge(merge(x, b), y);
}
AC:
int remake(int a, int b){
if(!b) return a;
int aa = tree[b].l, bb = tree[b].r;
tree[tree[b].l].fa = tree[b].l;
tree[tree[b].r].fa = tree[b].r;
tree[b].l = tree[b].r = 0;
tree[b].siz = 1;
int x, y;
split1(a, tree[b].w, x, y);
a = merge(merge(x, b), y);
a = remake(a, aa);
a = remake(a, bb);
return a;
}
这是两次的代码,b 向 a 合并。请问这是什么原因?