社区讨论

求大佬指点一下

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

讨论操作

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

当前回复
1 条
当前快照
1 份
快照标识符
@mi6ndud3
此快照首次捕获于
2025/11/20 07:42
4 个月前
此快照最后确认于
2025/11/20 07:42
4 个月前
查看原帖
过了样例,只有20分
CPP
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
typedef int ll;
ll sum[4100000+1],mx[4100000+1],a[4100000+1],dep[2000000+1],fa[2000000+1],e[2000000+1],son[2000000+1];
ll n,t,dd,dd1,dd2,dd3,cnt,k,q,rr,y1,y2,k2,k3,k4,k5,k6,mod;
ll siz[2000000+1],id[2000000+1],wt[2000000+1],top[2000000+1],po;
string k1;
struct roro
{
    ll to;
    ll nxt;
}jojo[4100000+1];
void add(ll a,ll b)
{
    cnt++;
    jojo[cnt].to=b;
    jojo[cnt].nxt=e[a];
    e[a]=cnt;
}
void build(ll l,ll r,ll v)
{
    if(l==r)
    {
        sum[v]=wt[l];
        mx[v]=wt[l];
        return;
    }
    ll mid=(l+r)/2;
    build(l,mid,2*v);
    build(mid+1,r,2*v+1);
    sum[v]=sum[2*v]+sum[2*v+1];
    mx[v]=max(mx[2*v],mx[2*v+1]);
    return;
}
/*void pushdown(ll rt,ll ln,ll rn)
{
    if(mark[rt]!=0)
    {
        mark[2*rt]=mark[2*rt]+mark[rt];
        mark[2*rt+1]=mark[2*rt+1]+mark[rt];
        sum[2*rt]=sum[2*rt]+mark[rt]*ln;
        sum[2*rt+1]=sum[2*rt+1]+mark[rt]*rn;
        mark[rt]=0;
    }
    return;
}*/
void push(ll l,ll r,ll v,ll q,ll C)
{
    if(l==r)
    {
        sum[v]=C;
        mx[v]=C;
        return;
    }
    ll mid=(l+r)/2;
    if(q<=mid)
    {
        push(l,mid,2*v,q,C);
    }
    else
    {
        push(mid+1,r,2*v+1,q,C);
    }
    sum[v]=sum[2*v]+sum[2*v+1];
    mx[v]=max(mx[2*v],mx[2*v+1]);
    return;
}
ll query1(ll L,ll R,ll l,ll r,ll v)
{
    if(L<=l && r<=R){   
        return sum[v];  
    }  
    int m=(l+r)/2;  
    ll ANS=0;  
    if(L<=m) ANS=query1(L,R,l,m,v*2)+ANS;  
    if(R>m) ANS=query1(L,R,m+1,r,v*2+1)+ANS;
    sum[v]=sum[2*v]+sum[2*v+1];
    mx[v]=max(mx[2*v],mx[2*v+1]);
    return ANS;
}
ll query2(ll L,ll R,ll l,ll r,ll v)
{
    if(L<=l && r<=R){   
        return mx[v];  
    }  
    int m=(l+r)/2;    
    ll ANS=-1e9;  
    if(L<=m) ANS=max(query2(L,R,l,m,v*2),ANS);  
    if(R>m) ANS=max(query2(L,R,m+1,r,v*2+1),ANS); 
    sum[v]=sum[2*v]+sum[2*v+1];
    mx[v]=max(mx[2*v],mx[2*v+1]);
    return ANS;
}
void dfs1(ll x,ll f,ll deep)
{
    dep[x]=deep;
    fa[x]=f;
    siz[x]=1;
    ll mson=-1;
    for(ll i=e[x];i!=0;i=jojo[i].nxt)
    {
        if(jojo[i].to!=f)
        {
            dfs1(jojo[i].to,x,deep+1);
            siz[x]=siz[x]+siz[jojo[i].to];
            if(siz[jojo[i].to]>mson)
            {
                mson=siz[jojo[i].to];
                son[x]=jojo[i].to;
            }
        }
    }
}
void dfs2(ll x,ll tp)
{
    k++;
    id[x]=k;
    wt[k]=a[x];
    top[x]=tp;
    if(son[x]!=0)
    {
        dfs2(son[x],tp);
        for(ll j=e[x];j!=0;j=jojo[j].nxt)
        {
            ll y=jojo[j].to;
            if(y!=son[x] and y!=fa[x])
            {
                dfs2(y,y);
            }
        }
    }
}
ll lianchamax(ll x,ll y)
{
    ll ans=-1e9;
    while(top[x]!=top[y])
    {
        if(dep[top[x]]<dep[top[y]])
        {
            swap(x,y);
        }
        ans=max(ans,query2(id[top[x]],id[x],1,n,1));
        x=fa[top[x]];
    }
    if(dep[x]>dep[y])
    {
        swap(x,y);
    }
    ans=max(ans,query2(id[x],id[y],1,n,1));
    return ans;
}
ll lianchasum(ll x,ll y)
{
    ll ans=0;
    while(top[x]!=top[y])
    {
        if(dep[top[x]]<dep[top[y]])
        {
            swap(x,y);
        }
        ans=ans+query1(id[top[x]],id[x],1,n,1);
        x=fa[top[x]];
    }
    if(dep[x]>dep[y])
    {
        swap(x,y);
    }
    ans=ans+query1(id[x],id[y],1,n,1);
    return ans;
}
int main()
{
  scanf("%d",&n);
  for(ll oo=1;oo<=n-1;oo++)
  {
      scanf("%d%d",&y1,&y2);
      add(y1,y2);
      add(y2,y1);
  }
  rr=1;
  for(ll p=1;p<=n;p++) 
  {
    scanf("%d",&a[p]);
  }  
  dfs1(rr,0,1);
  dfs2(rr,rr);
  build(1,n,1);
  ll ooo=0;
  scanf("%d",&t);
  for(ll mm=1;mm<=t;mm++)
  {
        cin>>k1;
      if(k1=="CHANGE")
      {
          scanf("%d%d",&k2,&k3);
          push(1,n,1,k2,k3);
      }
      else if(k1=="QMAX")
      {
          scanf("%d%d",&k2,&k3);
          ooo=lianchamax(k2,k3);
          printf("%d\n",ooo);
      }
      else if(k1=="QSUM")
      {
          scanf("%d%d",&k2,&k3);
          ooo=lianchasum(k2,k3);
          printf("%d\n",ooo);
      }
  }

回复

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

正在加载回复...