我乱改,改A了,但是不知道为什么,求助!
查看原帖
我乱改,改A了,但是不知道为什么,求助!
486001
Knighthood楼主2023/1/13 01:10

以下是AC代码:

#include <iostream>
#include <vector>
#include <stack>
#include <random>

using namespace std;

const int maxN = 1e5 + 5;

random_device seed;
mt19937 rd(seed());
vector<int> E[maxN];
int n, dep[maxN], f[maxN], top[maxN], sz[maxN], son[maxN], in[maxN], sign;
int w[maxN], c[maxN];
int rt[maxN];

struct Treap {
    int tot, sum[maxN], ch[maxN][2], pro[maxN], val[maxN], maxx[maxN], p[maxN];
    stack<int> st;

    void pushup(int x) {
        maxx[x] = max(max(maxx[ch[x][0]], maxx[ch[x][1]]), p[x]);
        sum[x] = sum[ch[x][0]] + sum[ch[x][1]] + p[x];
    }

    int newnode(int x, int y) {
        int k;
        if (!st.empty()) k = st.top(), st.pop();
        else k = ++tot;
        val[k] = x;
        sum[k] = maxx[k] = p[k] = y;
        pro[k] = (int) rd();
        return k;
    }

    void split(int &cur, int key, int &l, int &r) {
        if (!cur) return l = r = 0, void();
        if (val[cur] <= key) split(ch[cur][1], key, ch[l = cur][1], r);
        else split(ch[cur][0], key, l, ch[r = cur][0]);
        pushup(cur);
    }

    int merge(int u, int v) {
        if (!u || !v) return u | v;
        if (pro[u] < pro[v]) return ch[u][1] = merge(ch[u][1], v), pushup(u), u;
        else return ch[v][0] = merge(u, ch[v][0]), pushup(v), v;
    }

    void ins(int x, int y, int z) {
        int l, r;
        split(rt[x], y, l, r);
        rt[x] = merge(merge(l, newnode(y, z)), r);
    }

    void del(int x, int y) {
        int l, r, mid;
        split(rt[x], y, l, r);
        split(l, y - 1, l, mid);
        rt[x] = merge(merge(l, merge(ch[mid][0], ch[mid][1])), r);
        ch[mid][0] = ch[mid][1] = 0;
        sum[mid] = val[mid] = pro[mid] = maxx[mid] = 0;
        st.push(mid);
    }

    int querySum(int x, int L, int R) {
        int l, mid, r;
        split(rt[x], L - 1, l, mid);
        split(mid, R, mid, r);
        int res = sum[mid];
        rt[x] = merge(merge(l, mid), r);
        return res;
    }

    int queryMaxx(int x, int L, int R) {
        int l, mid, r;
        split(rt[x], L - 1, l, mid);
        split(mid, R, mid, r);
        int res = maxx[mid];
        rt[x] = merge(merge(l, mid), r);
        return res;
    }
} tr;

void Dfs1(int u, int fa) {
    f[u] = fa;
    dep[u] = dep[fa] + 1;
    sz[u] = 1;
    for (auto i: E[u]) {
        int v = i;
        if (v == fa) continue;
        Dfs1(v, u);
        sz[u] += sz[v];
        if (sz[son[u]] < sz[v]) son[u] = v;
    }
}

void Dfs2(int u, int sp) {
    top[u] = sp;
    in[u] = ++sign;
    if (son[u]) Dfs2(son[u], sp);
    for (auto i: E[u]) {
        int v = i;
        if (v == f[u] || v == son[u]) continue;
        Dfs2(v, v);
    }
}

int TcquerySum(int root, int u, int v) {
    int ans = 0;
    while (top[u] != top[v]) {
        if (dep[top[u]] < dep[top[v]]) swap(u, v);
        ans += tr.querySum(root, in[top[u]], in[u]);
        u = f[top[u]];
    }
    if (dep[u] > dep[v]) swap(u, v);
    ans += tr.querySum(root, in[u], in[v]);
    return ans;
}

int TcqueryMaxx(int root, int u, int v) {
    int ans = 0;
    while (top[u] != top[v]) {
        if (dep[top[u]] < dep[top[v]]) swap(u, v);
        ans = max(ans, tr.queryMaxx(root, in[top[u]], in[u]));
        u = f[top[u]];
    }
    if (dep[u] > dep[v]) swap(u, v);
    ans = max(ans, tr.queryMaxx(root, in[u], in[v]));
    return ans;
}

int main() {
#ifdef LOCAL
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#endif

    ios_base::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);

    int q;
    cin >> n >> q;
    for (int i = 1; i <= n; ++i) cin >> w[i] >> c[i];
    for (int i = 1; i < n; ++i) {
        int u, v;
        cin >> u >> v;
        E[u].emplace_back(v);
        E[v].emplace_back(u);
    }
    Dfs1(1, 0);
    Dfs2(1, 1);
    for (int i = 1; i <= n; ++i) tr.ins(c[i], in[i], w[i]);
    while (q--) {
        char op;
        int x, y;
        cin >> op >> op >> x >> y;
        if (op == 'C') {
            tr.del(c[x], in[x]);
            tr.ins(c[x] = y, in[x], w[x]);
        } else if (op == 'W') {
            tr.del(c[x], in[x]);
            tr.ins(c[x], in[x], w[x] = y);
        } else if (op == 'S') {
            cout << TcquerySum(c[x], x, y) << '\n';
        } else {
            cout << TcqueryMaxx(c[x], x, y) << '\n';
        }
    }

    return 0;
}

但是!把querySum和queryMaxx函数中的两个split改成以下:

split(rt[x], R, l, r);
split(l, L - 1, l, mid);

就会WA,这两个不是一个意思吗??

蒟蒻不理解,求大佬解释,感激不尽!

2023/1/13 01:10
加载中...