求助Treap做法用vector出现了玄学错误
查看原帖
求助Treap做法用vector出现了玄学错误
677124
picha楼主2023/8/29 15:54

Rt,我在 Treap 中用了 vector,在插入函数中因为是 vector 所以无法使用引用传递参数(也就是使用 ll &x)来修改 x 的值,所以改成了让插入函数返回 x 修改后的值。

结果如果使用 a[x].l = insrt(a[x].l, k); 直接修改 a[x].l 的值会导致 a[x].l 没有被修改,连样例都过不去;如果加一个变量进行过渡(比如 ll q = insrt(a[x].l, k); a[x].l = q;)就可以成功修改 a[x].l,并 AC。

请各位巨佬帮忙解答一下这个玄学错误是因为什么?

无法过样例的代码中的插入函数:

ll insrt(ll x, abc k) {
    ll p = x;
    if (x == 0) {
        p = new_nde(k);
        return p;
    }
    if (k < a[x].val || k == a[x].val) {
        a[x].l = insrt(a[x].l, k);
        // ll q = insrt(a[x].l, k);
        // a[x].l = q;
        pushup(x);
        if (a[x].rnd < a[a[x].l].rnd) {
            p = rrtt(x);
        }
    }
    else {
        a[x].r = insrt(a[x].r, k);
        // ll q = insrt(a[x].r, k);
        // a[x].r = q;
        pushup(x);
        if (a[x].rnd < a[a[x].r].rnd) {
            p = lrtt(x);
        }
    }
    return p;
}

AC 代码中的插入函数:

ll insrt(ll x, abc k) {
        ll p = x;
        if (x == 0) {
            p = new_nde(k);
            return p;
        }
        if (k < a[x].val || k == a[x].val) {
            // a[x].l = insrt(a[x].l, k);
            ll q = insrt(a[x].l, k);
            a[x].l = q;
            pushup(x);
            if (a[x].rnd < a[a[x].l].rnd) {
                p = rrtt(x);
            }
        }
        else {
            // a[x].r = insrt(a[x].r, k);
            ll q = insrt(a[x].r, k);
            a[x].r = q;
            pushup(x);
            if (a[x].rnd < a[a[x].r].rnd) {
                p = lrtt(x);
            }
        }
        return p;
    }

下面是完整的 AC 代码:(评测记录)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn = 100000;
const ll N = maxn + 10;
ll n, m, Q, x, y, res, fa[N];
char ch;
struct abc{
	ll x, y; // x is the importance of the node, and y is the id of the node.
	bool operator < (abc p) {
		return x < p.x;
	}
    bool operator == (abc p) {
        return x == p.x;
    }
}a[N];
struct nde{ 
    abc val;
    ll rnd, siz, l, r;
};
struct TRP{
    ll rt;
    vector<nde> a;
    void clr() {
        rt = 0;
        a.clear();
		a.push_back((nde){0, 0, 0, 0, 0});
    }
    ll new_nde(abc k) {
		a.push_back((nde){k, rand(), 1, 0, 0});
        return (ll)(a.size()) - 1;
    }
    void pushup(ll x) {
        a[x].siz = a[a[x].l].siz + a[a[x].r].siz + 1;
    }
    ll lrtt(ll x) {
        ll p = a[x].r;
        a[x].r = a[p].l;
        a[p].l = x;
        pushup(x);
        pushup(p);
        return p;
    }
    ll rrtt(ll x) {
        ll p = a[x].l;
        a[x].l = a[p].r;
        a[p].r = x;
        pushup(x);
        pushup(p);
        return p;
    }
    ll insrt(ll x, abc k) {
        ll p = x;
        if (x == 0) {
            p = new_nde(k);
            return p;
        }
        if (k < a[x].val || k == a[x].val) {
            // a[x].l = insrt(a[x].l, k);
            ll q = insrt(a[x].l, k);
            a[x].l = q;
            pushup(x);
            if (a[x].rnd < a[a[x].l].rnd) {
                p = rrtt(x);
            }
        }
        else {
            // a[x].r = insrt(a[x].r, k);
            ll q = insrt(a[x].r, k);
            a[x].r = q;
            pushup(x);
            if (a[x].rnd < a[a[x].r].rnd) {
                p = lrtt(x);
            }
        }
        return p;
    }
    abc get_val(ll x, ll k) {
        if (x == 0) {
            return (abc){-1, -1};
        }
        if (k == a[a[x].l].siz + 1) {
            return a[x].val;
        }
        else if (k <= a[a[x].l].siz) {
            return get_val(a[x].l, k);
        }
        else {
            return get_val(a[x].r, k - a[a[x].l].siz - 1);
        }
    }
}g[N];
ll get_fa(ll x) {
	if (fa[x] == x) {
		return x;
	}
	else {
		fa[x] = get_fa(fa[x]);
		return fa[x];
	}
}
void mrge(ll x, ll y) {
	ll p = get_fa(x), q = get_fa(y);
	if (p == q) {
		return;
	}
	if ((ll)(g[p].a.size()) < (ll)(g[q].a.size())) {
		swap(p, q);
	}
    fa[q] = p;
    for (ll i = 1; i < (ll)(g[q].a.size()); ++i) {
        g[p].rt = g[p].insrt(g[p].rt, g[q].a[i].val);
    }
    g[q].clr();
}
ll rd() {
	char ch = getchar();
	ll s = 0, w = 1;
	while (ch < '0' || ch > '9') {
		if (ch == '-') {
			w = -1;
		}
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		s = (s << 3) + (s << 1) + (ch ^ 48);
		ch = getchar();
	}
	return (s * w);
}
int main() {
	n = rd(); m = rd();
	for (ll i = 1; i <= n; ++i) {
		a[i].x = rd();
		a[i].y = i;
	}
	for (ll i = 1; i <= n; ++i) {
		fa[i] = i;
        g[i].clr();
        g[i].rt = g[i].insrt(g[i].rt, a[i]);
	}
	{ll u, v;
	for (ll i = 1; i <= m; ++i) {
		u = rd(); v = rd();
		mrge(u, v);
	}}
	Q = rd();
	for (ll i = 1; i <= Q; ++i) {
		cin >> ch;
		if (ch == 'Q') {
			x = rd(); y = rd();
            ll p = get_fa(x);
			res = g[p].get_val(g[p].rt, y).y;
            printf("%lld\n", res);
		}
		else {
			x = rd(); y = rd();
            mrge(x, y);
		}
	}
    return 0;
}

变量名和码风有些奇怪,请巨佬们不要吐槽。

2023/8/29 15:54
加载中...