树剖板子,玄学TLE,码风良好,悬关
查看原帖
树剖板子,玄学TLE,码风良好,悬关
856179
LiuQJun_271119楼主2024/1/28 14:22

rt

#include <bits/stdc++.h>
#define max(a, b) ((a) > (b) ? (a) : (b))
#define INF 2147483647

const int N = 1e5;

struct edge {
    int nxt, to;
} e[2 * N + 5];
struct node {
    int hson, siz, fa, dep, top, dfn;
} t[N + 5];
int n, tot, head[N + 5], cnt, rnk[N + 5], w[N + 5];
struct xdtree{
    int sum[4 * N + 5], mx[4 * N + 5];
    
    void pushup(int x) {sum[x] = sum[x << 1] + sum[x << 1 | 1], mx[x] = max(mx[x << 1], mx[x << 1 | 1]);}

    void build(int x, int l, int r) {
        if (l == r) {
            sum[x] = mx[x] = w[rnk[l]];
            return;
        }
        int mid = (l + r) >> 1;
        build(x << 1, l, mid);
        build(x << 1 | 1, mid + 1, r);
        pushup(x);
    }

    int querysum(int x, int s, int t, int l, int r) {
        if (l <= s && t <= r) return sum[x];
        int mid = (s + t) >> 1, res = 0;
        if (mid >= l) res += querysum(x << 1, s, mid, l, r);
        if (mid < r) res += querysum(x << 1 | 1, mid + 1, t, l, r);
        return res;
    }

    int querymx(int x, int s, int t, int l, int r) {
        if (l <= s && t <= r) return mx[x];
        int mid = (s + t) >> 1, res = -INF;
        if (mid >= l) res = max(res, querymx(x << 1, s, mid, l, r));
        if (mid < r) res = max(res, querymx(x << 1 | 1, mid + 1, t, l, r));
        return res;
    }

    void update(int x, int l, int r, int u, int k) {
        if (l == r) {
            sum[x] = mx[x] = k;
            return;
        }
        int mid = (l + r) >> 1;
        if (u <= mid) update(x << 1, l, mid, u, k);
        else update(x << 1 | 1, mid + 1, r, u, k);
        pushup(x);
    }
} st;

void add(int u, int v) {
    e[++tot] = {head[u], v};
    head[u] = tot;
}

void dfs1(int x, int fthr) {
    t[x] = {0, 1, fthr, t[fthr].dep + 1, 0, 0};
    for (int i = head[x]; i; i = e[i].nxt) {
        if (t[e[i].to].dep) continue;
        dfs1(e[i].to, x);
        t[x].siz += t[e[i].to].siz;
        if (t[t[x].hson].siz < t[e[i].to].siz) t[x].hson = e[i].to;
    }
}

void dfs2(int x, int k) {
    t[x].top = k;
    t[x].dfn = ++cnt;
    rnk[cnt] = x;
    if (!t[x].hson) return;
    dfs2(t[x].hson, k);
    for (int i = head[x]; i; i = e[i].nxt)
        if (e[i].to != t[x].hson && e[i].to != t[x].fa) dfs2(e[i].to, e[i].to);
}

int qmax(int u, int v) {
    int res = -INF;
    while (t[u].top != t[v].top) {
        if (t[t[u].top].dep < t[t[v].top].dep)
            std::swap(u, v);
        res = max(res, st.querymx(1, 1, n, t[t[u].top].dfn, t[u].dfn));
        u = t[t[u].top].fa;
    }
    if (t[u].dfn > t[v].dfn) std::swap(u, v);
    res = max(res, st.querymx(1, 1, n, t[u].dfn, t[v].dfn));
    return res;
}


int qsum(int u, int v) {
    int res = 0;
    while (t[u].top != t[v].top) {
        if (t[t[u].top].dep < t[t[v].top].dep)
            std::swap(u, v);
        res = res + st.querysum(1, 1, n, t[t[u].top].dfn, t[u].dfn);
        u = t[t[u].top].fa;
    }
    if (t[u].dfn > t[v].dfn) std::swap(u, v);
    res = res + st.querysum(1, 1, n, t[u].dfn, t[v].dfn);
    return res;
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i < n; i++) {
        int u, v; scanf("%d%d", &u, &v);
        add(u, v);
        add(v, u);
    }
    for (int i = 1; i <= n; i++)
        scanf("%d", w + i);
    dfs1(1, 0);
    dfs2(1, 1);
    st.build(1, 1, n);
    int q; scanf("%d", &q);
    while (q--) {
        char typ[10]; scanf("%s", typ + 1);
        int x, y; scanf("%d%d", &x, &y);
        if (!strcmp(typ + 1,"CHANGE")) st.update(1, 1, n, t[x].dfn, y);
        if (!strcmp(typ + 1, "QMAX")) printf("%d\n", qmax(x, y));
        if (!strcmp(typ + 1, "QSUM")) printf("%d\n", qsum(x, y));
    }
}

求dalao调

2024/1/28 14:22
加载中...