CF1656E Equal Tree Sums题解

其实这道题不难

首先假设 1 1 1 是根节点

我看到这道题第一反应就是直接假设整棵树权值之和是某一个定值,然后再dfs造每一个 a x a_x ax 。(其实到这里就可以a了,但是不优雅)

我们发现,由于去掉某一个节点之后,它所有的儿子所在的子树之和都和它上面那一部分之和是一样的,于是我们就有了: s u m x ′ s   s o n = s u m 1 − s u m x sum_{x's\ son}=sum_1-sum_x sumxs son=sum1sumx 其中( x ≠ 1 x\ne1 x=1,下同)

又因为: a x = s u m x − ∑ s u m x ′ s   s o n a_x=sum_x-\sum sum_{x's\ son} ax=sumxsumxs son

结合一下就成了 a x = s u m 1 − d e g x × ( s u m 1 − s u m x ) a_x=sum_1-deg_x\times(sum_1-sum_x) ax=sum1degx×(sum1sumx)

当我们令 s u m 1 = 0 sum_1=0 sum1=0 时,发现:

  • s u m x ′ s   s o n = − s u m x sum_{x's\ son}=-sum_x sumxs son=sumx
  • a x = d e g x ∗ s u m x a_x=deg_x*sum_x ax=degxsumx

我们再令 s u m x = ( − 1 ) d e p x sum_x=(-1)^{dep_x} sumx=(1)depx ,就可以发现 a x = d e g x ( − 1 ) d e p x a_x=deg_x(-1)^{dep_x} ax=degx(1)depx

不难发现,这个结论在 x = 1 x=1 x=1 时也成立

再手动构造几组小数据后发现构造方法正确,就可以优雅的写代码了,芜湖起飞!

最后献上我其丑无比的代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,ans[N];
vector<int>ed[N];
void dfs(int x,int fa,int k){
  ans[x]=ed[x].size()*k;
  for(int y:ed[x])if(fa!=y)dfs(y,x,-k);
}
void solve(){
  cin>>n;
  for(int i=1;i<=n;i++)ed[i].clear();
  for(int i=1,u,v;i<n;i++){
    cin>>u>>v;
    ed[u].emplace_back(v);
    ed[v].emplace_back(u);
  }
  dfs(1,1,1);
  for(int i=1;i<=n;i++)cout<<ans[i]<<" ";
  cout<<'\n';
}
int main(){
  int t;
  cin>>t;
  while(t--)solve();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值