树剖30pts求助
查看原帖
树剖30pts求助
475419
AsoltA楼主2023/4/27 14:25
#include <bits/stdc++.h>
#define int long long
const int SZ=3e5+10;
char op[11];
int n,m,head[SZ],hhh,siz[SZ],son[SZ],dep[SZ],faz[SZ],dfn[SZ],top[SZ],rk[SZ],cnt,a[SZ];
struct edge
{
    int nxt,to;
} g[SZ*2];
struct node
{
    int l,r,maxx,sum;
} t[SZ*4];
void pushup(int p)
{
    t[p].sum=t[p<<1].sum+t[p<<1|1].sum;
    t[p].maxx=std::max(t[p<<1].maxx,t[p<<1|1].maxx);
}
void build(int p,int l,int r)
{
    t[p].l=l;
    t[p].r=r;
    if(l==r)
    {
        t[p].sum=a[rk[l]];
        t[p].maxx=a[rk[l]];
        return;
    }
    int mid=(l+r)>>1;
    build(p<<1,l,mid);
    build(p<<1|1,mid+1,r);
    pushup(p);
}
void modify(int p,int x,int v)
{
    if(t[p].l==t[p].r)
    {
        t[p].maxx=v;
        t[p].sum=v;
        return;
    }
    int mid=(t[p].l+t[p].r)>>1;
    if(x<=mid)
    {
        modify(p<<1,x,v);
    }
    else
    {
        modify(p<<1|1,x,v);
    }
    pushup(p);
}
int query1(int p,int l,int r)
{
    if(t[p].l==t[p].r)
    {
        return t[p].sum;
    }
    int ret=0;
    if(t[p<<1].r>=l)
    {
        ret+=query1(p<<1,l,r);
    }
    if(t[p<<1|1].l<=r)
    {
        ret+=query1(p<<1|1,l,r);
    }
    pushup(p);
    return ret;
}
int query2(int p,int l,int r)
{
    if(t[p].l==t[p].r)
    {
        return t[p].maxx;
    }
    int ret=-1e9;
    if(t[p<<1].r>=l)
    {
        ret=std::max(ret,query2(p<<1,l,r));
    }
    if(t[p<<1|1].l<=r)
    {
        ret=std::max(ret,query2(p<<1|1,l,r));
    }
    pushup(p);
    return ret;
}
void add_edge(int u,int v)
{
    g[++hhh].nxt=head[u];
    head[u]=hhh;
    g[hhh].to=v;
}
void dfs1(int u,int fa)
{
    siz[u]=1;
    son[u]=0;
    for(int i=head[u];i;i=g[i].nxt)
    {
        int v=g[i].to;
        if(v!=fa)
        {
            dep[v]=dep[u]+1;
            faz[v]=u;
            dfs1(v,u);
            siz[u]+=siz[v];
            if(siz[v]>siz[son[u]])
            {
                son[u]=v;
            }
        }
    }
}
void dfs2(int u,int x)
{
    ++cnt;
    dfn[u]=cnt;
    rk[cnt]=u;
    top[u]=x;
    if(son[u])
    {
        dfs2(son[u],x);
    }
    for(int i=head[u];i;i=g[i].nxt)
    {
        int v=g[i].to;
        if(!(v==faz[u]||v==son[u]))
        {
            dfs2(v,v);
        }
    }
}
int query_tree_1(int u,int v)
{
    int ret=0;
    while(top[u]!=top[v])
    {
        if(dep[top[u]]<dep[top[v]])
        {
            std::swap(u,v);
        }
        ret+=query1(1,dfn[top[u]],dfn[u]);
        u=faz[top[u]];
    }
    if(dep[u]<dep[v])
    {
        std::swap(u,v);
    }
    ret+=query1(1,dfn[v],dfn[u]);
    return ret;
}
int query_tree_2(int u,int v)
{
    int ret=-1e9;
    while(top[u]!=top[v])
    {
        if(dep[top[u]]<dep[top[v]])
        {
            std::swap(u,v);
        }
        ret=std::max(ret,query2(1,dfn[top[u]],dfn[u]));
        u=faz[top[u]];
    }
    if(dep[u]<dep[v])
    {
        std::swap(u,v);
    }
    ret=std::max(ret,query2(1,dfn[v],dfn[u]));
    return ret;
}
signed main()
{
    scanf("%lld",&n);
    for(int i=1;i<n;i++)
    {
        int u,v;
        scanf("%lld%lld",&u,&v);
        add_edge(u,v);
        add_edge(v,u);
    }
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
    }
    dep[1]=1;
    faz[1]=1;
    dfs1(1,0);
    dfs2(1,1);
    build(1,1,n);
    scanf("%lld",&m);
    while(m--)
    {
        int u,v;
        scanf("%s%lld%lld",&op,&u,&v);
        if(op[1]=='H')
        {
            modify(1,dfn[u],v);
        }
        if(op[1]=='M')
        {
            printf("%lld\n",query_tree_2(u,v));
        }
        if(op[1]=='S')
        {
            printf("%lld\n",query_tree_1(u,v));
        }
    }
    return 0;
}
2023/4/27 14:25
加载中...