社区讨论

MLE 求助qwq

P2590[ZJOI2008] 树的统计参与者 4已保存回复 7

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
7 条
当前快照
1 份
快照标识符
@mi865a4s
此快照首次捕获于
2025/11/21 09:15
4 个月前
此快照最后确认于
2025/11/21 09:15
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
#define mst(a,b) memset(a,b,sizeof(a))
#define For(i, k, j) for(int i = (k); i <= (j); i++)
#define INF 2147483647
#define eps 1e-4
using namespace std;
inline int read()
{
    int num = 0; char c=' '; int flag = 1;
    for(;c>'9'||c<'0';c=getchar()) if(c=='-') flag = -1;
    for(;c>='0'&&c<='9';num=(num<<1)+(num<<3)+c-48,c=getchar());
    return num * flag;
}
int n, Qnum;
#define MAXN 100005
struct Edge {
    int v, nxt;
}e[MAXN << 1];
int lst[MAXN], tot = 0;
inline void addedge(int u, int v) {
    e[++tot] = (Edge) {v, lst[u]};
    lst[u] = tot;
} 
int fa[MAXN], siz[MAXN], dep[MAXN];
int fir[MAXN], pos[MAXN], Num = 0;
void dfs1(int u, int Fa) {
    fa[u] = Fa, siz[u] = 1;
    for(int i = lst[u]; i; i = e[i].nxt) {
        int v = e[i].v; if(v == Fa) return;
        dep[v] = dep[u] + 1;
        dfs1(v, u);
        siz[u] += siz[v];
    } 
}
void dfs2(int u, int chain) {
    fir[u] = chain, pos[u] = ++Num;
    int maxi = -1, maxv = -1;
    for(int i = lst[u]; i; i = e[i].nxt) {
        int v = e[i].v; if(v == fa[u]) continue;
        if(siz[v] > maxv)
            maxv = siz[v], maxi = v;
    }
    if(maxi == -1) return;
    dfs2(maxi, chain);
    for(int i = lst[u]; i; i = e[i].nxt) {
        int v = e[i].v;
        if(v != fa[u] && v != maxi)
            dfs2(v, v);
    }
    return;
}
int sum[MAXN << 2], maxi[MAXN << 2];
#define ls (k << 1)
#define rs (k << 1 | 1)
#define mid ((l + r) >> 1)
void pushup(int k) {
    sum[k] = sum[ls] + sum[rs];
    maxi[k] = max(maxi[ls], maxi[rs]);
}
void update(int k, int l, int r, int pos, int val) {
    if(l == pos && r == pos) {sum[k] = maxi[k] = val; return;}
    if(pos <= mid) update(ls, l, mid, pos, val);
    else update(rs, mid+1, r, pos, val);
    pushup(k);
}
int querymax(int k, int l, int r, int ql, int qr) {
//  cout << l << ' ' << r << ' ' << mid << ' ' << ql << ' ' << qr << endl;
//  For(i, 1, 500000000);
    if(l == ql && r == qr)return maxi[k];
    if(qr <= mid) return querymax(ls, l, mid, ql, qr);
    else if(ql > mid) return querymax(rs, mid+1, r, ql, qr);
    else return max(querymax(ls, l, mid, ql, mid), querymax(rs, mid+1, r, mid+1, qr));
}
int querysum(int k, int l, int r, int ql, int qr) {
    if(l == ql && r == qr)return sum[k];
    if(qr <= mid) return querysum(ls, l, mid, ql, qr);
    else if(ql > mid) return querysum(rs, mid+1, r, ql, qr);
    else return querysum(ls, l, mid, ql, mid) + querysum(rs, mid+1, r, mid+1, qr);
}
int Getmax(int x, int y) {
    int ans = - (1 << 30);
    while(fir[x] != fir[y]) {
//      cout << "*" <<' ' << x << ' ' << y << endl;
        if(dep[fir[x]] < dep[fir[y]]) swap(x, y);
        ans = max(ans, querymax(1, 1, n, pos[fir[x]], pos[x]));
        x = fa[fir[x]];
    }
    if(pos[x] > pos[y]) swap(x, y);
    ans = max(ans, querymax(1, 1, n, pos[x], pos[y]));
    return ans;
}
int Getsum(int x, int y) {
    int ans = 0;
    while(fir[x] != fir[y]) {
        if(dep[fir[x]] < dep[fir[y]]) swap(x, y);
        ans += querysum(1, 1, n, pos[fir[x]], pos[x]);
        x = fa[fir[x]];
    }
    if(pos[x] > pos[y]) swap(x, y);
    ans += querysum(1, 1, n, pos[x], pos[y]);
    return ans;
}
signed main()
{
    n = read();
    for(int i = 1; i < n; i++) {
        int u = read(), v = read();
        addedge(u, v); addedge(v, u);
    }
    memset(sum, 0, sizeof(sum));
    memset(maxi, -126, sizeof(maxi));
    memset(dep, 0, sizeof(dep));
    memset(fa, 0, sizeof(fa));
    memset(fir, 0, sizeof(fir));
    memset(siz, 0, sizeof(siz));
    memset(pos, 0, sizeof(pos));
    Num = 0, dep[0] = -1;
    dfs1(1, 0);
    dfs2(1, 1);
    for(int i = 1; i <= n; i++) {
        int val; scanf("%d", &val);
        update(1, 1, n, pos[i], val);
    }
    int Qnum = read();
    while(Qnum--) {
        char opt[10]; int a, b;
        scanf("%s %d %d", opt, &a, &b);
        if(opt[1] == 'H') {
            update(1, 1, n, pos[a], b);
        } else if(opt[1] == 'M') {
            printf("%d\n", Getmax(a, b));
        } else {
            printf("%d\n", Getsum(a, b));
        }
    }
    return 0;
}
/*

*/```

回复

7 条回复,欢迎继续交流。

正在加载回复...