社区讨论

萌新求助 WA 20pts

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

讨论操作

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

当前回复
7 条
当前快照
1 份
快照标识符
@lobt9jp4
此快照首次捕获于
2023/10/30 02:35
2 年前
此快照最后确认于
2023/11/04 07:03
2 年前
查看原帖
希望各位大佬能够帮助萌新蒟蒻。
不知道错在哪里/kk。
CPP
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
using namespace std;
#define uLL unsigned LL
#define INF 0x3f3f3f3f
#define LL long long
#define reg register
#define rs (rt<<1|1)
#define ls (rt<<1)
#define N 30005
inline LL read(){
    LL s=0, f=1; char c=getchar();
    while(!isdigit(c)) { if(c=='-') f=-f; c=getchar(); }
    while(isdigit(c)) s=(s<<3)+(s<<1)+(c^48), c=getchar();
    return s*f;
}
struct Node {
    int mx, sm;
    Node () { mx=-INF, sm=0; }
} tr[N<<2|1];
int n, q, a[N];
int tot, t[N+N+1], nt[N+N+1], head[N];
int cnt, f[N], rk[N], son[N], siz[N], dep[N], top[N], dfn[N];
inline void Add(int x, int y) { t[++tot]=y, nt[tot]=head[x], head[x]=tot; }
inline void PushUp(int rt) { tr[rt].mx=max(tr[ls].mx, tr[rs].mx), tr[rt].sm=tr[ls].sm+tr[rs].sm; }
inline void DFS1(int r, int fa){
    f[r]=fa, dep[r]=dep[fa]+1, siz[r]=1;
    for(reg int i=head[r]; i; i=nt[i]){
        if(t[i]==fa) continue;
        DFS1(t[i], r); siz[r]+=siz[t[i]];
        if(siz[t[i]]>siz[son[r]]) son[r]=t[i];
    }
}
inline void DFS2(int r, int tp){
    top[r]=tp, dfn[r]=++cnt, rk[cnt]=r;
    if(son[r]) DFS2(son[r], tp);
    for(reg int i=head[r]; i; i=nt[i]){
        if(t[i]==f[r]) continue;
        if(t[i]==son[r]) continue;
        DFS2(t[i], t[i]);
    }
}
inline void Build(int rt, int l, int r){
    if(l==r) { tr[rt].mx=tr[rt].sm=a[rk[l]]; return ; }
    int mid=(l+r)>>1;
    Build(ls, l, mid), Build(rs, mid+1, r);
    PushUp(rt);
}
inline void Modify(int rt, int l, int r, int u, int w){
    if(l==r) { tr[rt].sm=tr[rt].mx=w; return ; }
    int mid=(l+r)>>1;
    if(u<=mid) Modify(ls, l, mid, u, w);
    else Modify(rs, mid+1, r, u, w);
    PushUp(rt);
}
inline int Query_Max(int rt, int l, int r, int u, int v){
    if(u<=l&&r<=v) return tr[rt].mx;
    int ans=-INF, mid=(l+r)>>1;
    if(u<=mid) ans=max(ans, Query_Max(ls, l, mid, u, v));
    if(v>mid) ans=max(ans, Query_Max(rs, mid+1, r, u, v));
    PushUp(rt);
    return ans;
}
inline int Query_Sum(int rt, int l, int r, int u, int v){
    if(u<=l&&r<=v) return tr[rt].sm;
    int ans=0, mid=(l+r)>>1;
    if(u<=mid) ans+=Query_Sum(ls, l, mid, u, v);
    if(v>mid) ans+=Query_Sum(rs, mid+1, r, u, v);
    PushUp(rt);
    return ans;
}
inline int Max(int x, int y){
    int mx=-INF;
    if(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]) swap(x, y);
        mx=max(mx, Query_Max(1, 1, n, dfn[top[x]], dfn[x]));
        x=f[top[x]];
    }
    if(dep[x]>dep[y]) swap(x, y);
    mx=max(mx, Query_Max(1, 1, n, dfn[x], dfn[y]));
    return mx;
}
inline int Sum(int x, int y){
    int sm=0;
    if(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]) swap(x, y);
        sm+=Query_Sum(1, 1, n, dfn[top[x]], dfn[x]);
        x=f[top[x]];
    }
    if(dep[x]>dep[y]) swap(x, y);
    sm+=Query_Sum(1, 1, n, dfn[x], dfn[y]);
    return sm;
}
int main(){
    n=read();
    for(reg int i=1; i<n; ++i){
        int x=read(), y=read(); 
        Add(x, y), Add(y, x);
    }
    for(reg int i=1; i<=n; ++i) a[i]=read();
    DFS1(1, 0), DFS2(1, 1), Build(1, 1, n);
    q=read();
    while(q--){
        char op[9]; scanf("%s", op);
        int x=read(), y=read(); 
        if(op[1]=='H') Modify(1, 1, n, dfn[x], y);
        if(op[1]=='M') printf("%d\n", Max(x, y));
        if(op[1]=='S') printf("%d\n", Sum(x, y));
    }
    return 0;
}

回复

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

正在加载回复...