萌新刚学C++,有点问题

P3391 【模板】文艺平衡树

SunnyYuan @ 2023-07-08 22:46:04

在平衡树中,

是通过懒标记来实现旋转,

在pushdown时,为什么

swap(tr[u].l, tr[u].r);

是对的,而

swap(tr[tr[u].l], tr[tr[u].r])

却是错的?

AC代码中的pushdown:

void pushdown(int u) {
    if (tr[u].tag) {
        tr[tr[u].l].tag ^= 1;
        tr[tr[u].r].tag ^= 1;
        swap(tr[u].l, tr[u].r);
        tr[u].tag ^= 1;
    }
}

by osky123456 @ 2023-07-08 23:07:20

更换的是父节点的左右子树吧,后者改变树的结构了,应该是吧


by SunnyYuan @ 2023-07-08 23:26:02

@osky123456 为什么改变了树的结构?


by osky123456 @ 2023-07-09 09:33:47

@SmallestRubbish 你把父亲节点改变了,其子树的父亲不就变了吗,前者相当于把左右子树互换


by SunnyYuan @ 2023-07-09 09:40:45

@osky123456

不会呀,交换的时候 l, r 一起带走了,相当于它的子树也一起交换了。


by reveal @ 2023-07-09 09:42:14

@SmallestRubbish 我怀疑是因为没判断儿子为空导致 tr[0] 出现了奇怪的东西。

另外这样写有点慢。


by osky123456 @ 2023-07-09 09:45:13

@osky123456 可是你的父亲节点的左右儿子指代还对吗


by SunnyYuan @ 2023-07-09 09:45:16

@reveal 好有道理


by SunnyYuan @ 2023-07-09 09:45:42

@osky123456 对的哦,它的子节点又没有变


by SunnyYuan @ 2023-07-09 09:51:32

@osky123456 @reveal

谢谢你们,原因找到了,就是在某次交换的时候把 tr[0] 赋值上了一个 tr[x] 的值导致空节点被附上了一个点。


|