zoukankan      html  css  js  c++  java
  • Final Zadanie 题解

    题意

    给出一棵树,求一组 (a_i), 满足:

    [Large operatorname{dist(1,1)} imes a_1+operatorname{dist(1,2)} imes a_2+dotsoperatorname{dist(1,n)} imes a_n=b_1\Large operatorname{dist(2,1)} imes a_1+operatorname{dist(2,2)} imes a_2+dotsoperatorname{dist(2,n)} imes a_n=b_2\Large vdots\Large operatorname{dist(n,1)} imes a_1+operatorname{dist(n,2)} imes a_2+dotsoperatorname{dist(n,n)} imes a_n=b_n ]


    题解

    考虑算贡献 ?

    (f_i) 表示第 (i) 个结点子树的 (a) 和。

    (g_i) 表示第 (i) (dots) (f)

    (Large f_1-2 imes f_i=b_i-b_{fa_i})

    上面这个式子直接用图形理解应该会方便一点。

    此外,

    (Large b_1=g_1-f_1=sumlimits_{i=1}^n f_i-f_1=sumlimits_{i=2}^n f_i)

    所以

    (Large 2 imes b_1=2 imes sumlimits_{i=2}^nf_idots①)

    因此

    [Large sum_{i=1}^n f_1-2 imes f_i = sum_{i=1}^n b_i-b_{fa_i} ]

    [Large n imes f_1-sum_{i=1}^n 2 imes f_i=sum b_i-sum b_{fa_i} ]

    则:

    [Large sum_{i=2}^n(b_i-b_{fa_i})=(n-1) imes f_1-sum_{i=2}^n2 imes f_i dots ② ]

    所以:

    [Large ①+②:sum_{i=2}^n(b_i-b_{fa_i})+2 imes b_1=(n-1) imes f_1 ]

    得到了:

    [Large f_1=dfrac{2 imes b_1+sumlimits_{i=2}^n(b_i-b_{fa_i})}{n-1} ]

    那么结合

    [Large f_1-2 imes f_i=b_i-b_{fa_i} ]

    ,就可以求到每一个 (f_i) 了,然后再搜一遍得到 (a_i) 即可。


    代码

    #include <cstdio>
    #include <vector>
    #include <algorithm>
    #define ll long long
    using namespace std;
    vector <int> G[300005];
    ll a[300005],f[300005],b[300005];
    ll sum=0;
    void dfs(int u,int fa,int op)
    {
    	if(op==1&&fa) sum+=b[u]-b[fa];
    	else if(op==2&&fa) f[u]=(f[1]-b[u]+b[fa])/2,a[u]=f[u];
    	else if(op==2&&!fa) a[u]=f[1];
    	for(int i=0;i<G[u].size();i++)
    	{
    		int v=G[u][i];
    		if(v==fa) continue;
    		dfs(v,u,op);
    		if(op==2) a[u]-=f[v];
    	}
    }
    int main() {
    	int n;
    	scanf("%d",&n);
    	for(int i=1,u,v;i<n;i++)
    	{
    		scanf("%d %d",&u,&v);
    		G[u].push_back(v);
    		G[v].push_back(u);
    	}
    	for(int i=1;i<=n;i++) scanf("%lld",&b[i]);
    	sum+=2ll*b[1];
    	dfs(1,0,1);
    	f[1]=sum/(n-1);
    	dfs(1,0,2);
    	for(int i=1;i<=n;i++) printf("%lld ",a[i]);
    	return 0;
    }
    
  • 相关阅读:
    显示器面板参数
    解决SQL Server 2008安装时提示:重新启动计算机 失败
    SQL Server 的 TSQL 语句的性能评估方法
    判断字母大小写
    linux发展史简介
    下载route命令源码
    TCP糊涂窗口综合症
    QT显示中文
    TCP四个定时器 之 TCP坚持定时器
    android 去ListView滑动阴影
  • 原文地址:https://www.cnblogs.com/Azazel/p/13916841.html
Copyright © 2011-2022 走看看