关于修改、查询的一点疑问
查看原帖
关于修改、查询的一点疑问
726992
ccxswl楼主2023/7/12 20:26

在修改、查询的代码中,有注释的几行代码,还有上面的一行代码,想问为什么上面的哪行代码是对的。

拿查询举例,现在想要查询 uu , vv 两个节点之间的最大值。

可是idx[x]+1可能不是 uu , vv 之间的那个 lcalca 的儿子的那个节点。因为idx[x]+1显然是 lca节点dfs的第一个节点, 所以idx[x]+1可能并不是 uu 、vv 之间的节点,有可能会多算边。

但实际上两种写法都能ac

#include <bits/stdc++.h>

using namespace std;

const int maxN = 1e5 + 7;

int st[maxN], ed[maxN], dis[maxN];
int V[maxN];
vector<int> E[maxN];

int cnt, rk[maxN], idx[maxN];
int fa[maxN], top[maxN], siz[maxN], son[maxN], dep[maxN];
void dfs1(int x, int f) {
    siz[x] = 1;
    dep[x] = dep[f] + 1;
    fa[x] = f;
    for (auto to : E[x]) {
        if (to == f) continue;
        dfs1(to, x);
        siz[x] += siz[to];
        if (siz[to] > siz[son[x]]) son[x] = to;
    }
}
void dfs2(int x, int tp) {
    top[x] = tp;
    idx[x] = ++cnt;
    rk[cnt] = x;
    if (!son[x]) return;
    dfs2(son[x], tp);
    for (auto to : E[x]) {
        if (to == fa[x] || to == son[x]) continue;
        dfs2(to, to);
    }
}

struct Tree {
    int l, r;
    int v;
    int tg, lz;
} t[maxN << 2];
#define ls (cur << 1)
#define rs (cur << 1 | 1)
void upd(int cur) {
    t[cur].v = max(t[ls].v, t[rs].v);
}
void build(int L, int R, int cur) {
    t[cur].l = L;
    t[cur].r = R;
    if (L == R) {
        t[cur].v = dis[rk[L]];
        return;
    }
    int mid = (L + R) >> 1;
    build(L, mid, ls);
    build(mid + 1, R, rs);
    upd(cur);
}
void M(Tree &res, int tg, int lz) {
    if (lz) res.v = lz, res.lz = lz, res.tg = 0;
    if (tg) res.v += tg, res.tg += tg;
}
void down(int cur) {
    if (!t[cur].lz && !t[cur].tg) return;
    M(t[ls], t[cur].tg, t[cur].lz);
    M(t[rs], t[cur].tg, t[cur].lz);
    t[cur].lz = t[cur].tg = 0;
}
void modify(int L, int R, int V, int cur, int type) {
    if (L <= t[cur].l && t[cur].r <= R) {
        if (type == 1) {
            t[cur].tg = 0;
            t[cur].lz = V;
            t[cur].v = V;
        }
        if (type == 2) {
            t[cur].tg += V;
            t[cur].v += V;
        }
    } else {
        down(cur);
        int mid = (t[cur].l + t[cur].r) >> 1;
        if (L <= mid) modify(L, R, V, ls, type);
        if (R > mid) modify(L, R, V, rs, type);
        upd(cur);
    }
}
int query(int L, int R, int cur) {
    if (L <= t[cur].l && t[cur].r <= R) return t[cur].v;
    down(cur);
    int mid = (t[cur].l + t[cur].r) >> 1, res = -2e9;
    if (L <= mid) res = max(res, query(L, R, ls));
    if (R > mid) res = max(res, query(L, R, rs));
    return res;
}

void R1(int x, int y, int z) {
    while (top[x] != top[y]) {
        if (dep[top[x]] < dep[top[y]]) swap(x, y);
        modify(idx[top[x]], idx[x], z, 1, 1);
        x = fa[top[x]];
    }
    if (dep[x] > dep[y]) swap(x, y);
    
    modify(idx[x] + 1, idx[y], z, 1, 1);
    
    // int now = rk[idx[x] + 1];
    // while (top[y] != top[now]) now += siz[now];
    // modify(idx[now], idx[y], z, 1, 1);
}
void R2(int x, int y, int z) {
    while (top[x] != top[y]) {
        if (dep[top[x]] < dep[top[y]]) swap(x, y);
        modify(idx[top[x]], idx[x], z, 1, 2);
        x = fa[top[x]];
    }
    if (dep[x] > dep[y]) swap(x, y);
    
    modify(idx[x] + 1, idx[y], z, 1, 2);

    // int now = rk[idx[x] + 1];
    // while (top[y] != top[now]) now += siz[now];
    // modify(idx[now], idx[y], z, 1, 2);
}
void R3(int x, int y) {
    int ans = -2e9;

    while (top[x] != top[y]) {
        if (dep[top[x]] < dep[top[y]]) swap(x, y);
        ans = max(ans, query(idx[top[x]], idx[x], 1));
        x = fa[top[x]];
    }
    if (dep[x] > dep[y]) swap(x, y);

    ans = max(ans, query(idx[x] + 1, idx[y], 1));

    // int now = rk[idx[x] + 1];
    // while (top[y] != top[now]) now += siz[now];
    // ans = max(ans, query(idx[now], idx[y], 1));
    
    cout << ans << '\n';
}

int n;

int main() {
    // freopen("P4315_1.in", "r", stdin);
    // freopen("P4315_1.ans", "w", stdout);
    cin >> n;
    for (int i = 1; i < n; i++) {
        cin >> st[i] >> ed[i] >> V[i];
        int x = st[i], y = ed[i];
        E[x].push_back(y);
        E[y].push_back(x);
    }
    dfs1(1, 0);
    dfs2(1, 1);
    for (int i = 1; i < n; i++) {
        int fx = idx[st[i]], fy = idx[ed[i]];
        if (fx < fy) dis[ed[i]] = V[i], V[i] = ed[i];
        else dis[st[i]] = V[i], V[i] = st[i];
    }

    build(1, n, 1);

    string s;
    do {
        cin >> s;
        if (s == "Change") {
            int k, w;
            cin >> k >> w;
            modify(idx[V[k]], idx[V[k]], w, 1, 1);
        }
        if (s == "Cover") {
            int x, y, z;
            cin >> x >> y >> z;
            R1(x, y, z);
        }
        if (s[0] == 'A') {
            int x, y, z;
            cin >> x >> y >> z;
            R2(x, y, z);
        }
        if (s[0] == 'M') {
            int x, y;
            cin >> x >> y;
            R3(x, y);
        }
    } while (s != "Stop");
}
/*
5
1 2 9
1 4 5
2 3 7
2 5 7
Max 2 3
Cover 1 4 14
Add 2 5 7
Max 1 5
Stop

5
1 2 1
1 3 3
1 4 9
3 5 7
Cover 5 4 1
Max 5 4
Stop

10
1 2 3
1 3 9
1 4 88
1 9 56
2 5 6 
2 6 1
5 7 4
9 8 7
9 10 55
Max 7 10
Cover 7 8 999
Max 7 10
Cover 7 8 1
Max 3 8
Stop
*/
2023/7/12 20:26
加载中...