30pts求调,玄2关
查看原帖
30pts求调,玄2关
774876
HashHacker_Peas楼主2025/7/21 08:30

rt,树剖板子AC on #5#6#9,能帮看一下吗?玄2关

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=3e4+10;
int n,q,u,v,val[maxn],dep[maxn],son[maxn],top[maxn],s[maxn],rnk[maxn],dfn[maxn],fa[maxn],tot;
vector<int>g[maxn];
string opt;
struct tree{
    int l,r,sum,val;
}tr[maxn<<2];
void dfs1(int x,int fath){
    dep[x]=dep[fath]+1,s[x]=1,fa[x]=fath;
    for(int i=0;i<g[x].size();i++){
        int to=g[x][i];
        if(to==fath)
            continue;
        dfs1(to,x);
        s[x]+=s[to];
        if(!son[x]||s[son[x]]<s[to])
            son[x]=to;
    }
}
void dfs2(int x,int t){
    top[x]=t,dfn[x]=++tot,rnk[tot]=x;
    if(son[x])
        dfs2(son[x],t);
    for(int i=0;i<g[x].size();i++){
        int to=g[x][i];
        if(to==son[x]||to==fa[x])
            continue;
        dfs2(to,to);
    }
}
void push_up(int p){
    tr[p].sum=tr[p<<1].sum+tr[p<<1|1].sum;
    tr[p].val=max(tr[p<<1].val,tr[p<<1|1].val);
}
void build(int p,int l,int r){
    tr[p].l=l,tr[p].r=r;
    if(l==r){
        tr[p].sum=tr[p].val=val[rnk[l]];
        return;
    }
    int mid=l+r>>1;
    build(p<<1,l,mid),build(p<<1|1,mid+1,r);
    push_up(p);
}
void update(int p,int x,int v){
    if(tr[p].l==tr[p].r){
        tr[p].sum=tr[p].val=v;
        return;
    }
    int mid=tr[p].l+tr[p].r>>1;
    if(mid>=x)
        update(p<<1,x,v);
    else update(p<<1|1,x,v);
    push_up(p);
}
int queryval(int p,int l,int r){
    if(l<=tr[p].l&&tr[p].r<=r)
        return tr[p].val;
    int mid=tr[p].l+tr[p].r>>1,ans=INT_MIN;
    if(mid>=l)
        ans=max(ans,queryval(p<<1,l,r));
    if(mid<r)
        ans=max(ans,queryval(p<<1|1,l,r));
    return ans;
}
int querysum(int p,int l,int r){
    if(l<=tr[p].l&&tr[p].r<=r)
        return tr[p].sum;
    int mid=tr[p].l+tr[p].r>>1,ans=0;
    if(mid>=l)
        ans+=querysum(p<<1,l,r);
    if(mid<r)
        ans+=querysum(p<<1|1,l,r);
    return ans;
}
int linkerval(int u,int v){
    int ans=INT_MIN;
    while(top[u]!=top[v]){
        if(dep[top[u]]<dep[top[v]])
            swap(u,v);
        ans=max(ans,queryval(1,dfn[top[u]],dfn[u]));
        u=fa[top[u]];
    }
    if(dep[u]>dep[v])
        swap(u,v);
    ans=max(ans,queryval(1,min(dfn[u],dfn[v]),max(dfn[u],dfn[v])));
    return ans;
}
int linkersum(int u,int v){
    int ans=0;
    while(top[u]!=top[v]){
        if(dep[top[u]]<dep[top[v]])
            swap(u,v);
        ans+=querysum(1,dfn[top[u]],dfn[u]);
        u=fa[top[u]];
    }
    if(dep[u]>dep[v])
        swap(u,v);
    ans+=querysum(1,min(dfn[u],dfn[v]),max(dfn[u],dfn[v]));
    return ans;
}
signed main(){
    ios::sync_with_stdio(false),cin.tie(0);
    cin>>n;
    for(int i=1;i<n;i++){
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    for(int i=1;i<=n;i++)
        cin>>val[i];
    dfs1(1,0),dfs2(1,0);
    build(1,1,n);
    cin>>q;
    while(q--){
        cin>>opt>>u>>v;
        if(opt=="CHANGE")
            update(1,dfn[u],v);
        if(opt=="QSUM")
            cout<<linkersum(dfn[u],dfn[v])<<"\n";
        if(opt=="QMAX")
            cout<<linkerval(dfn[u],dfn[v])<<"\n";
    }
    return 0;
}
2025/7/21 08:30
加载中...