zoukankan      html  css  js  c++  java
  • BZOJ 3727 DP?推式子..

     思路:

    设$sum[i]表示i的子树中a[i]的和$

    $b[1]=Sigma a[i]*dis[i] = Sigma _{i=2} ^n sum[i]$

    $b[x]-b[fa[x]]=sum[1]-2*sum[x]$

    $sum[1]={Sigma_{i=2}^n (b[x]-b[fa[x]])+2*b[1] over n-1}$

    $求出sum[1]以后根据a[x]=sum[x]-Sigma_{v是x的儿子} sum[v]带入求出其它值即可$

    $复杂度O(n)$

    //By SiriusRen
    #include <cstdio>
    #include <cstring>
    using namespace std;
    #define int long long
    const int N=600500;
    int n,xx,yy,first[N],next[N],v[N],tot,fa[N],rev[N],cnt,b[N],X;
    long long sum[N],ans[N];
    void add(int x,int y){v[tot]=y,next[tot]=first[x],first[x]=tot++;}
    void dfs(int x){
        rev[++cnt]=x;
        for(int i=first[x];~i;i=next[i])if(v[i]!=fa[x])
            fa[v[i]]=x,dfs(v[i]);
    }
    void dfs2(int x){
        ans[x]=sum[x];
        for(int i=first[x];~i;i=next[i])if(v[i]!=fa[x])
            dfs2(v[i]),ans[x]-=sum[v[i]];
    }
    signed main(){
        memset(first,-1,sizeof(first));
        scanf("%lld",&n);
        for(int i=1;i<n;i++)scanf("%lld%lld",&xx,&yy),add(xx,yy),add(yy,xx);
        for(int i=1;i<=n;i++)scanf("%lld",&b[i]);
        dfs(1);
        for(int i=2;i<=n;i++)sum[1]+=(b[i]-b[fa[i]]);
        sum[1]=(sum[1]+2*b[1])/(n-1);
        for(int i=2;i<=n;i++)X=rev[i],sum[X]=(sum[1]-b[X]+b[fa[X]])/2;
        dfs2(1);
        for(int i=1;i<=n;i++)printf("%lld%c",ans[i],i!=n?' ':'
    ');
    }
  • 相关阅读:
    mysql日期加减
    cron 配置计划任务的书写格式(quartz 时间配置)
    空值排序问题
    update 表名 set 字段=值,数据更新
    insert into 数据插入
    SQL里面的char类型
    SQL使用代码创建数据完整性,约束
    SQL制表
    sql创建数据库
    验证码
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6667250.html
Copyright © 2011-2022 走看看