原来帖子沉了,求帮助,20pts
  • 板块学术版
  • 楼主月T成
  • 当前回复5
  • 已保存回复5
  • 发布时间2022/1/25 20:08
  • 上次更新2023/10/28 10:58:08
查看原帖
原来帖子沉了,求帮助,20pts
109450
月T成楼主2022/1/25 20:08
#include <bits/stdc++.h>
#define ll long long
#define lc p<<1
#define rc p<<1|1
#define N 200005
using namespace std;

int n,m,cnt;
int rnk[N],dfn[N],a[N],son[N],size[N],dep[N],fa[N],top[N];//rnk[dfn[x]]=x
int ver[N],Next[N],head[N],tot;
void add(int x,int y)
{
    ver[++tot]=y,Next[tot]=head[x],head[x]=tot;
}

struct SegTree{
    int sum[N<<2],maxn[N<<2];
    void update(int p)
    {
        sum[p]=sum[lc]+sum[rc];
        maxn[p]=max(maxn[lc],maxn[rc]);
    }
    void build(int p,int l,int r)
    {
        if (l==r)
        {
            sum[p]=maxn[p]=a[rnk[l]];
            return;
        }
        int mid=(l+r)>>1;
        build(lc,l,mid);
        build(rc,mid+1,r);
        update(p);
    }
    void change(int p,int l,int r,int x,int s)
    {
        if (l==r)
        {
            sum[p]=maxn[p]=s;
            return ;
        }
        int mid=(l+r)>>1;
        if (x<=mid)change(lc,l,mid,x,s);
        else change(rc,mid+1,r,x,s);
        update(p);
    }
    int askmax(int p,int l,int r,int L,int R)
    {
        if (l>=L&&r<=R)return maxn[p];
        int mid=(l+r)>>1,val=INT_MIN;
        if (L<=mid)val=max(val,askmax(lc,l,mid,L,R));
        if (R>mid)val=max(val,askmax(rc,mid+1,r,L,R));
        return val;
    }
    int asksum(int p,int l,int r,int L,int R)
    {
        if (l>=L&&r<=R)return sum[p];
        int mid=(l+r)>>1,val=0;
        if (L<=mid)val+=asksum(lc,l,mid,L,R);
        if (R>mid)val+=asksum(rc,mid+1,r,L,R);
        return val;
    }
}t;

void dfs1(int x)
{
    son[x]=-1;
    size[x]=1;
    for (int i=head[x];i;i=Next[i])
    {
        int y=ver[i];
        if (dep[y])continue;
        dep[y]=dep[x]+1;
        fa[y]=x;
        dfs1(y);
        size[x]+=size[y];
        if (son[x]==-1||size[y]>size[son[x]])son[x]=y;
    }
}
void dfs2(int x,int T)
{
    top[x]=T;
    dfn[x]=++cnt;
    rnk[cnt]=x;
    if (son[x]==-1)return;
    dfs2(son[x],T);
    for (int i=head[x];i;i=Next[i])
    {
        int y=ver[i];
        if (y!=son[x]&&y!=fa[x])dfs2(y,y);
    }
}
int qmax(int x,int y)
{
    int val=INT_MIN,fx=top[x],fy=top[y];
    while (fx!=fy)
    {
        if (dep[fx]>=dep[fy])val=max(val,t.askmax(1,1,n,dfn[fx],dfn[x])),x=fa[fx];
        else val=max(val,t.askmax(1,1,n,dfn[fy],dfn[y])),y=fa[fy];
        fx=top[x],fy=top[y];
    }
    if (dfn[x]<dfn[y])val=max(val,t.askmax(1,1,n,dfn[x],dfn[y]));
    else val=max(val,t.askmax(1,1,n,dfn[y],dfn[x]));
    return val;
}
int qsum(int x,int y)
{
    int val=0,fx=top[x],fy=top[y];
    while (fx!=fy)
    {
        if (dep[fx]>=dep[fy])val+=t.asksum(1,1,n,dfn[fx],dfn[x]),x=fa[fx];
        else val+=t.asksum(1,1,n,dfn[fy],dfn[y]),y=fa[fy];
        fx=top[x],fy=top[y];
    }
    if (dfn[x]<dfn[y])val+=t.asksum(1,1,n,dfn[x],dfn[y]);
    else val+=t.asksum(1,1,n,dfn[y],dfn[x]);
    return val;
}
int main()
{
    cin>>n;
    for (int i=1,x,y;i<n;i++)
    {
        cin>>x>>y;
        add(x,y),add(y,x);
    }
    for (int i=1;i<=n;i++)cin>>a[i];
    dep[1]=1;
    dfs1(1);
    // cout<<"OK dfs1"<<endl;
    dfs2(1,1);
    // cout<<"OK dfs2"<<endl;
    t.build(1,1,n);
    cin>>m;
    while (m--)
    {
        string op;
        int u,v;
        cin>>op>>u>>v;
        if (op=="CHANGE")t.change(1,1,n,u,v);
        if (op=="QMAX")printf("%d\n",qmax(u,v));
        if (op=="QSUM")printf("%d\n",qsum(u,v));
    }
    return 0;
}

2022/1/25 20:08
加载中...