zoukankan      html  css  js  c++  java
  • 【题解】HDU4625 JZPTREE

    题目链接

    题意

    给定一棵 n 点的树,定义 (dis(u,v)) 为树上路径长度。对于每个点,定义 (E_u=sum_{v=1}^n dis(u,v)^k) ,其中 k 为给定数。

    求每个 (E_imod 10007 (i=1sim n)) .

    思路

    求幂可以考虑转化成第二类斯特林数。有公式: (x^n = sum_{k=0}^n egin{Bmatrix} n \ k end{Bmatrix} x^{underline{k}}.)

    从而 (E_u = sum_{v=1}^n (dis(u, v))^k = sum_{i=0}^k egin{Bmatrix} k \ i end{Bmatrix} sum_{v=1}^n (dis(u, v))^{underline{i}}.)

    (f[u][k] = sum_{v in T_u} (dis(u, v))^{underline{k}},) (T_u)(u) 为根的子树,且显然有 ((x+1)^{underline{k}} = x^{underline{k}}+kx^{underline{k-1}})

    考虑求 (f[u][k].)

    [f[u][k]=sum_{vin T_u} dis(u,v)^{underline{k}} =sum_{vin son(u)}sum_{win T_v}[dis(v,w)+1]^{underline{k}} ]

    这时候就可以运用上述公式。

    [f[u][k]=sum_{vin son(u)}sum_{win T_v} [dis(v,w)^{underline{k}}+k imes dis(v,w)^{underline{k-1}}] ]

    回到 (f[u][k]) 的定义,可得到转移方程

    [f[u][k]=sum_{vin son(u)} f[v][k]+k imes f[v][k-1] ]

    两遍 DFS 即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=5e4+10,K=510,mod=10007;
    int n,k,S[N][K],f[N][K],g[N][K];
    vector<int> v[N];
    
    void dfs1( int x,int fa )
    {
            f[x][0]=1; 
            for ( int i=1; i<=k; i++ ) f[x][i]=0;
            for ( auto y : v[x] )
            {
                    if ( y==fa ) continue;
                    dfs1( y,x );
                    f[x][0]=(f[x][0]+f[y][0])%mod;
                    for ( int i=1; i<=k; i++ )
                            f[x][i]=( f[x][i]+(f[y][i]+i*f[y][i-1]))%mod;
            }
    }
    
    void dfs2( int x,int fa )
    {
            if ( !fa ) for ( int i=0; i<=k; i++ ) g[x][i]=f[x][i];
            for ( auto y : v[x] )
            {
                    if ( y==fa ) continue;
                    g[y][0]=g[x][0];
                    for ( int i=1; i<=k; i++ )
                    {
                            int t1=(g[x][i]-(f[y][i]+i*f[y][i-1]))%mod;
                            int t2=( g[x][i-1]-( f[y][i-1]+(i-1)*(i-2>=0 ? f[y][i-2] : 0) ))%mod;
                            g[y][i]=( f[y][i]+( t1+i*t2) )%mod;
                    }
                    dfs2( y,x );
            }
    }
    
    void init()
    {
            S[0][0]=1;
            for ( int i=1; i<=500; i++ )
             for ( int j=1; j<=i; j++ )
                    S[i][j]=(S[i-1][j-1]+S[i-1][j]*j)%mod;
    }
    
    int main()
    {
            int T; scanf( "%d",&T ); init();
            while ( T-- )
            {
                    scanf( "%d%d",&n,&k );
                    for ( int i=1; i<=n; i++ )
                            v[i].clear();
                    for ( int i=1,x,y; i<n; i++ )
                            scanf( "%d%d",&x,&y ),v[x].push_back(y),v[y].push_back(x);
                    
                    dfs1( 1,0 ); dfs2( 1,0 );
    
                    for ( int x=1;x<=n; x++ )
                    {
                            int res=0;
                            for ( int i=0; i<=k; i++ )
                                    res=( res+S[k][i]*g[x][i])%mod;
                            printf( "%d
    ",(res+mod)%mod );
                    }
            }
    }
    
  • 相关阅读:
    C# 多线程 弹出模态MessageBox的一种方法
    CentOS 7安装Docker
    CentOS 6 安装Docker
    docker三要素
    openstack_dashboard无法获取nova
    cinder安装与配置
    Dashboard安装与配置
    openstack-neutron安装与配置
    openstack在controller节点使用openstack network agent list不显示计算节点
    nova安装与配置
  • 原文地址:https://www.cnblogs.com/UntitledCpp/p/13913840.html
Copyright © 2011-2022 走看看