zoukankan      html  css  js  c++  java
  • [PA2014]Zadanie

    [PA2014]Zadanie

    题目大意:

    一棵(n(nle3 imes10^5))个点的树,每个点上有(a_i)个人。树上所有人到(i)号点距离之和为(b_i)。已知({b_i}),求({a_i})

    思路:

    (1)号点为根,定义(par[i])(i)的父结点,(size[i])(i)子树内总人数,(tot)为总点数。则有:

    [b_i=b_{par[i]}+tot-2size[i] ]

    移项,得:

    [b_i-b_{par[i]}=tot-2size[i] ]

    对除根以外的所有结点求和,则有:

    [sum_{i=2}^n(b_i-b_{par[i]})=(n-1)tot-2sum_{i=2}^n size[i] ]

    其中(sum_{i=2}^n size[i]=b_1),于是我们可以求出(tot),然后求出(size[i])(a_i)了。

    源代码:

    #include<cstdio>
    #include<cctype>
    #include<vector>
    inline int getint() {
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return x;
    }
    typedef long long int64;
    const int N=3e5+1;
    std::vector<int> e[N];
    inline void add_edge(const int &u,const int &v) {
    	e[u].push_back(v);
    	e[v].push_back(u);
    }
    int64 tot;
    int a[N],b[N],size[N],par[N];
    void dfs(const int &x,const int &par) {
    	::par[x]=par;
    	tot+=x!=1?b[x]-b[par]:b[1]*2;
    	for(unsigned i=0;i<e[x].size();i++) {
    		const int &y=e[x][i];
    		if(y==par) continue;
    		dfs(y,x);
    	}
    }
    int main() {
    	const int n=getint();
    	for(register int i=1;i<n;i++) {
    		add_edge(getint(),getint());
    	}
    	for(register int i=1;i<=n;i++) {
    		b[i]=getint();
    	}
    	dfs(1,0);
    	tot/=n-1;
    	a[1]=size[1]=tot;
    	for(register int i=2;i<=n;i++) {
    		a[i]=size[i]=(b[par[i]]-b[i]+tot)/2;
    	}
    	for(register int i=2;i<=n;i++) {
    		a[par[i]]-=size[i];
    	}
    	for(register int i=1;i<=n;i++) {
    		printf("%d%c",a[i]," 
    "[i==n]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    【转】算法的时间复杂度
    FFT 物理意义(转)
    【转】FIR学习1
    【转】DFT DTFT DFS FFT的关系
    【转】TCL中的数组
    【转】setup time和hold time的周期问题(slack)
    【转】TCL语法简介
    【转】亚稳态分析
    ubuntu下Samba服务器搭建
    第一次生成uImage出现的问题解决
  • 原文地址:https://www.cnblogs.com/skylee03/p/10206965.html
Copyright © 2011-2022 走看看