zoukankan      html  css  js  c++  java
  • CF 954H Path Counting

    H. Path Counting
    time limit per test
    5 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    You are given a rooted tree. Let's denote d(x) as depth of node x: depth of the root is 1, depth of any other node x is d(y) + 1, where yis a parent of x.

    The tree has the following property: every node x with d(x) = i has exactly ai children. Maximum possible depth of a node is n, and an = 0.

    We define fk as the number of unordered pairs of vertices in the tree such that the number of edges on the simple path between them is equal to k.

    Calculate fk modulo 109 + 7 for every 1 ≤ k ≤ 2n - 2.

    Input

    The first line of input contains an integer n (2  ≤  n  ≤  5 000) — the maximum depth of a node.

    The second line of input contains n - 1 integers a1,  a2,  ...,  an - 1 (2 ≤  ai  ≤ 109), where ai is the number of children of every node xsuch that d(x) = i. Since an = 0, it is not given in the input.

    Output

    Print 2n - 2 numbers. The k-th of these numbers must be equal to fk modulo 109 + 7.

    Examples
    input
    Copy
    4
    2 2 2
    
    output
    Copy
    14 19 20 20 16 16 
    input
    Copy
    3
    2 3
    
    output
    Copy
    8 13 6 9 
    Note

    This the tree from the first sample:

     

    【题意】

    给出一棵深度为n的树,其中每个深度为i的节点都有a[i]个儿子。问对于每个k,有多少条简单路径满足其长度恰好为k

    n<=5000

     

    【分析】

    考虑枚举路径的端点。

    d[i,j]表示从某个深度为i的节点开始,只往下走且长度为j的路径条数。那么d[i,j]显然等于i的子树中深度为i+j的点数。

    u[i,j]表示从某个深度为i的节点开始,第一步必须往上走,且路径长度为j的方案。

    有两种转移,一种是走到父亲后继续往上,贡献就等于u[i-1,j-1]。另一种转移是走到父亲后就开始往下走,贡献就等于u[i,j-2]*(a[i-1]-1)

    综上,f[i][j]= f[i+1][j-1]*a[i]+

    f[i-1][j-1]+

    f[i][j-2]*(a[i-1]-1);

     

    【代码】

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define debug(x) cerr<<#x<<" "<<x<<'
    ';
    using namespace std;
    typedef long long ll;
    const int N=5005;
    const ll mod=1e9+7;
    const ll rev=5e8+4;
    int n,a[N],p[N],f[N][N<<1],ans[N<<1];
    int main(){
    	scanf("%d",&n);p[0]=1;
    	for(int i=1;i<n;i++) scanf("%d",&a[i]),p[i]=(ll)p[i-1]*a[i]%mod;
    	for(int i=n;i;i--){
    		f[i][0]=1;
    		for(int j=1;j<=n-i;j++){
    			f[i][j]=(ll)f[i+1][j-1]*a[i]%mod;
    			ans[j]=((ll)ans[j]+(ll)f[i][j]*p[i-1])%mod;
    		}
    	}
    	for(int i=1;i<=n;i++){
    		for(int j=2*n-2;j>=1;j--){
    			f[i][j]=f[i-1][j-1];
    			if(i>1&&j>1&&j-2<n&&j<=i+n-2) f[i][j]=((ll)f[i][j]+(ll)f[i][j-2]*(a[i-1]-1))%mod;
    			ans[j]=((ll)ans[j]+(ll)f[i][j]*p[i-1])%mod;
    		}
    	}
    	for(int i=1;i<=2*n-2;i++) printf("%I64d ",(ll)ans[i]*rev%mod);
    	return 0;
    } 
  • 相关阅读:
    python 装饰器
    python 环境迁移之requirements.txt (window环境)
    selenium 元素查找与属性
    pytest+allure(allure-pytest基于这个插件)设计定制化报告
    Capability配置
    python_excel
    python_连接mysql
    MySql_1
    appium_环境搭建
    appium_appium简介
  • 原文地址:https://www.cnblogs.com/shenben/p/10424160.html
Copyright © 2011-2022 走看看