WA30求助 只能过#5#6#9
查看原帖
WA30求助 只能过#5#6#9
787229
kdx_dy楼主2023/7/1 12:36
#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 5;
int n, u, v, q, tmp;
int w[N], dfn[N], _dfn[N], fa[N], dep[N], sz[N], son[N], top[N];
char s[26];
vector<int> edge[N];
struct node {
    int val, l, r;
} maxtree[N << 2], sumtree[N << 2];
void dfs1(int T, int f) {
    dfn[T] = ++tmp;
    _dfn[tmp] = T;
    sz[T] = 1;
    fa[T] = f;
    dep[T] = dep[f] + 1;
    for (int i = 0; i < edge[T].size(); i++) {
        if (edge[T][i] == f)
            continue;
        dfs1(edge[T][i], T);
        sz[T] += sz[edge[T][i]];
        if (sz[edge[T][i]] > sz[son[T]])
            son[T] = edge[T][i];
    }
    return;
}
void dfs2(int T, int tp) {
    top[T] = tp;
    if (!son[T])
        return;
    dfs2(son[T], tp);
    for (int i = 0; i < edge[T].size(); i++) {
        if (edge[T][i] == fa[T] || edge[T][i] == son[T])
            continue;
        dfs2(edge[T][i], edge[T][i]);
    }
    return;
}
void build(int T, int l, int r) {
    maxtree[T].l = sumtree[T].l = l;
    maxtree[T].r = sumtree[T].r = r;
    if (l == r) {
        maxtree[T].val = sumtree[T].val = w[_dfn[l]];
        return;
    }
    int mid = (l + r) >> 1;
    build(T << 1, l, mid);
    build(T << 1 | 1, mid + 1, r);
    maxtree[T].val = max(maxtree[T << 1].val, maxtree[T << 1 | 1].val);
    sumtree[T].val = sumtree[T << 1].val + sumtree[T << 1 | 1].val;
    return;
}
int querymax(int T, int l, int r) {
    if (l <= maxtree[T].l && maxtree[T].r <= r)
        return maxtree[T].val;
    int mid = (maxtree[T].l + maxtree[T].r) >> 1, ret = -N;
    if (r <= mid)
        ret = max(ret, querymax(T << 1, l, r));
    if (l > mid)
        ret = max(ret, querymax(T << 1 | 1, l, r));
    if (l <= mid && r > mid)
        ret = max(querymax(T << 1, l, r), querymax(T << 1 | 1, l, r));
    return ret;
}
int querysum(int T, int l, int r) {
    if (l <= sumtree[T].l && sumtree[T].r <= r)
        return sumtree[T].val;
    int mid = (sumtree[T].l + sumtree[T].r) >> 1, ret = 0;
    if (r <= mid)
        ret += querysum(T << 1, l, r);
    if (l > mid)
        ret += querysum(T << 1 | 1, l, r);
    if (l <= mid && r > mid)
        ret = querysum(T << 1, l, r) + querysum(T << 1 | 1, l, r);
    return ret;
}
void change(int T) {
    if (maxtree[T].l == maxtree[T].r) {
        w[T] = maxtree[T].val = sumtree[T].val = v;
        return;
    }
    int mid = (maxtree[T].l + maxtree[T].r) >> 1;
    if (u <= mid)
        change(T << 1);
    if (u > mid)
        change(T << 1 | 1);
    maxtree[T].val = max(maxtree[T << 1].val, maxtree[T << 1 | 1].val);
    sumtree[T].val = sumtree[T << 1].val + sumtree[T << 1 | 1].val;
    return;
}
void qmax(int A, int B) {
    int ans = -N;
    while (top[A] != top[B]) {
        if (dep[top[A]] < dep[top[B]])
            swap(A, B);
        ans = max(ans, querymax(1, dfn[top[A]], dfn[A]));
        A = fa[top[A]];
    }
    if (dep[A] < dep[B])
        swap(A, B);
    ans = max(ans, querymax(1, dfn[B], dfn[A]));
    printf("%d\n", ans);
    return;
}
void qsum(int A, int B) {
    int ans = 0;
    while (top[A] != top[B]) {
        if (dep[top[A]] < dep[top[B]])
            swap(A, B);
        ans += querysum(1, dfn[top[A]], dfn[A]);
        A = fa[top[A]];
    }
    if (dep[A] < dep[B])
        swap(A, B);
    ans += querysum(1, dfn[B], dfn[A]);
    printf("%d\n", ans);
    return;
}
int main() {
    scanf("%d", &n);
    for (int i = 1; i < n; i++) {
        scanf("%d%d", &u, &v);
        edge[u].push_back(v);
        edge[v].push_back(u);
    }
    for (int i = 1; i <= n; i++) scanf("%d", &w[i]);
    dfs1(1, 0);
    dfs2(1, 1);
    build(1, 1, n);
    scanf("%d", &q);
    while (q--) {
        scanf("%s%d%d", s + 1, &u, &v);
        if (s[2] == 'H')
            u = dfn[u], change(1);
        if (s[2] == 'M')
            qmax(u, v);
        if (s[2] == 'S')
            qsum(u, v);
    }
    return 0;
}
2023/7/1 12:36
加载中...