萌新求助树剖 50pts
查看原帖
萌新求助树剖 50pts
610557
shinzanmonoszm 妹妹楼主2022/12/23 09:49

#include<iostream>
#include<algorithm>
const int sz = 3e4 + 10;
int arr[sz], n, q;
struct ST {
    struct node {
        int sum, max;
        node operator+(const node &a) const {
            return node{sum + a.sum, std::max(max, a.max)};
        }
    };
    node tree[sz << 2];
    void build(int p, int ln, int rn) {
        if (ln == rn) return tree[p] = node{arr[ln], arr[ln]}, void();
        int mid = ln + rn >> 1;
        build(p << 1, ln, mid);
        build(p << 1 | 1, mid + 1, rn);
        tree[p] = tree[p << 1] + tree[p << 1 | 1];
    }
    void change(int p, int ln, int rn, int pos, int val) {
        if (ln == rn) return tree[p] = node{val, val}, void();
        int mid = ln + rn >> 1;
        if (pos <= mid) change(p << 1, ln, mid, pos, val);
        else change(p << 1 | 1, mid + 1, rn, pos, val);
        tree[p] = tree[p << 1] + tree[p << 1 | 1];
    }
    int querymax(int p, int ln, int rn, int l, int r) {
        if (ln >= l && rn <= r) return tree[p].max;
        if (ln > r || rn < l) return -0x7fffffff;
        int mid = ln + rn >> 1, res = -0x7fffffff;
        res = std::max(res, querymax(p << 1, ln, mid, l, r));
        res = std::max(res, querymax(p << 1 | 1, mid + 1, rn, l, r));
        return res;
    }
    int querysum(int p, int ln, int rn, int l, int r) {
        if (ln >= l && rn <= r) return tree[p].sum;
        if (ln > r || rn < l) return 0;
        int mid = ln + rn >> 1, res = 0;
        res += querysum(p << 1, ln, mid, l, r);
        res += querysum(p << 1 | 1, mid + 1, rn, l, r);
        return res;
    }
} st;
struct edge {
    int nxt, to;
} graph[sz << 1];
int hpp, head[sz];
void addEdge(int from, int to) {
    graph[++hpp] = edge{head[from], to};
    head[from] = hpp;
}
int top[sz], hson[sz], ssz[sz], dfn[sz], dpp, fa[sz], dep[sz];
void buildDFS(int u, int fau) {
    dep[u] = dep[fau] + 1, ssz[u] = 1, fa[u] = fau;
    for (int p = head[u]; p; p = graph[p].nxt) {
        int v = graph[p].to;
        if (v == fau) return;
        buildDFS(v, u);
        ssz[u] += ssz[v];
        if (ssz[v] > ssz[hson[u]]) hson[u] = v;
    }
}
void chainDFS(int u, int t) {
    dfn[u] = ++dpp, top[u] = t;
    if (!hson[u]) return;
    chainDFS(hson[u], t);
    for (int p = head[u]; p; p = graph[p].nxt) {
        int v = graph[p].to;
        if (v == hson[u] || v == fa[u]) continue;
        chainDFS(v, v);
    }
}
int querymax(int u, int v) {
    int res = -0x7fffffff;
    while (top[u] != top[v]) {
        if (dep[top[u]] < dep[top[v]]) std::swap(u, v);
        res = std::max(res, st.querymax(1, 1, n, dfn[top[u]], dfn[u]));
        u = fa[top[u]];
    }
    if (dfn[u] > dfn[v]) std::swap(u, v);
    res = std::max(res, st.querymax(1, 1, n, dfn[u], dfn[v]));
    return res;
}
int querysum(int u, int v) {
    int res = 0;
    while (top[u] != top[v]) {
        if (dep[top[u]] < dep[top[v]]) std::swap(u, v);
        res += st.querysum(1, 1, n, dfn[top[u]], dfn[u]);
        u = fa[top[u]];
    }
    if (dfn[u] > dfn[v]) std::swap(u, v);
    res += st.querysum(1, 1, n, dfn[u], dfn[v]);
    return res;
}
int main() {
    std::ios::sync_with_stdio(false);
    std::cin >> n;
    for (int i = 1, u, v; i < n; i++) {
        std::cin >> u >> v;
        addEdge(u, v), addEdge(v, u);
    }
    buildDFS(1, 0);
    chainDFS(1, 1);
    for (int i = 1; i <= n; i++) std::cin >> arr[dfn[i]];
    st.build(1, 1, n);
    std::cin >> q;
    while (q--) {
        std::string op;
        int x, y;
        std::cin >> op >> x >> y;
        if (op == "CHANGE") st.change(1, 1, n, dfn[x], y);
        else if (op == "QMAX") std::cout << querymax(x, y) << "\n";
        else std::cout << querysum(x, y) << "\n";
    }
    return 0;
}
2022/12/23 09:49
加载中...