BZOJ3727: PA2014 Final Zadanie

来源:互联网 发布:霜叶知秋的意思 编辑:程序博客网 时间:2024/06/03 05:37

BZOJ3727: PA2014 Final Zadanie

乱搞

题解:

感谢fqk dalao

画柿子!
令点1为根,设dis[i]表示i到根的深度,易得:

b[1]=a[i]dis[i]

b[i]=b[fai]size[i]+(size[1]size[i])(i>1)

a[i]=size[i]size[soni]

根据以上式子,我们有了size[i](i>1)size[1]的关系,和a[i]size[i]的关系,所以就可以得到a[i]size[1]的关系,又因为b[1]=a[i]×dis[i],所以可以得到b[1]size[1]的关系,就得到了size[1],然后就能求出所有的a[i]了。

Code:

#include <iostream>#include <cstring>#include <cstdio>#define D(x) cout<<#x<<" = "<<x<<"  "#define E cout<<endlusing namespace std;const int N = 300005;int n,dis[N],b[N];struct Edge{    int to, next;} e[N*2];int head[N], ec;void add(int a, int b){    ec++; e[ec].to=b; e[ec].next=head[a]; head[a]=ec;}struct Data{    double k,b;    Data (double _k=0, double _b=0) { k=_k; b=_b; }    Data operator + (Data x) { return Data(k+x.k, b+x.b); }    Data operator - (Data x) { return Data(k-x.k, b-x.b); }    Data operator * (double x) { return Data(k*x, b*x); }} a[N], size[N];double ans[N],size1;void dfs(int u, int f){    size[u]=Data(0.5,(b[f]-b[u])*0.5);    a[u]=size[u];    for(int i=head[u];i;i=e[i].next){        int v=e[i].to;        if(v==f) continue;        dis[v]=dis[u]+1;        dfs(v,u);        a[u]=a[u]-size[v];    }}int main(){    freopen("a.in","r",stdin);    scanf("%d",&n);    int u,v;    for(int i=1;i<n;i++){        scanf("%d%d",&u,&v);        add(u,v); add(v,u);    }       for(int i=1;i<=n;i++) scanf("%d",&b[i]);    dfs(1,0);    Data tp;    for(int i=2;i<=n;i++) tp=tp+(a[i]*(double)dis[i]);    ans[1]=size1=((double)(b[1]-tp.b))/tp.k;    for(int i=2;i<=n;i++){        ans[i]=a[i].k*size1+a[i].b;        ans[1]-=ans[i];    }    for(int i=1;i<=n;i++) printf("%lld%c",(long long)ans[i],i==n?'\n':' ');}