CF 954H Path Counting
5 seconds
256 megabytes
standard input
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.
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.
Print 2n - 2 numbers. The k-th of these numbers must be equal to fk modulo 109 + 7.
4
2 2 2
14 19 20 20 16 16
3
2 3
8 13 6 9
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<<'\n';
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;
}
CF 954H Path Counting的更多相关文章
- Codeforces 954H Path Counting 【DP计数】*
Codeforces 954H Path Counting LINK 题目大意:给你一棵n层的树,第i层的每个节点有a[i]个儿子节点,然后问你树上的简单路径中长度在1~n*2-2之间的每个有多少条 ...
- Codeforces 954H Path Counting(DP)
题目链接 Path Counting 题意 给定一棵高度为$n$的树,给出每一层的每个点的儿子个数(某一层的所有点儿子个数相同). 令$f_{k}$为长度为$k$的路径条数,求$f_{1}, ...
- CF Covered Path (贪心)
Covered Path time limit per test 1 second memory limit per test 256 megabytes input standard input o ...
- cf 990G - GCD Counting
题意 #include<bits/stdc++.h> #define t 200000 #define MAXN 200100 using namespace std; int n; in ...
- CF954H Path Counting
一开始的想法是枚举路径的 \(\rm LCA\) 然后再枚举两边的深度,但是这样无论如何我都只能做到 \(O(n ^ 3)\) 的复杂度. 只能考虑换一种方式计数,注意到点分治可以解决树上一类路径问题 ...
- Educational Codeforces Round 40 (Rated for Div. 2) Solution
从这里开始 小结 题目列表 Problem A Diagonal Walking Problem B String Typing Problem C Matrix Walk Problem D Fig ...
- Ubuntu 12 修改环境变量
Ubuntu Linux系统包含两类环境变量:系统环境变量和用户环境变量.系统环境变量对所有系统用户都有效,用户环境变量仅仅对当前的用户有效. 修改用户环境变量 用户环境变量通常被存储在下面的文件中: ...
- bzoj3876: [Ahoi2014&Jsoi2014]支线剧情
题意:给一幅图,从1开始,每条边有边权最少走一遍,可以在任意点退出,问最小花费 题解:上下界费用流,每个边都流一遍,然后为了保证流量平衡,新建源点汇点,跑费用流把流量平衡 /************* ...
- 2015-2016 ACM-ICPC, NEERC, Moscow Subregional Contest J - Jealousy
题意:有n张照片,每张照片上有一些妹子,要按照片顺序给妹纸安排男朋友,如果妹纸i安排的男朋友之前有女朋友,那么费用+wi,求总费用最小,和输出路径 题解:费用流,先把照片天数建点i连i+1,流量k(最 ...
随机推荐
- apache 通过ajp访问tomcat多个站点
copy mod_jk.so to modules下 httpd的配置项中添加如下内容 LoadModule proxy_module modules/mod_proxy.so LoadModule ...
- Spring Date JPA 更新部分字段
在Spring Data JPA 中,新增和更新操作都是用save()的方式进行,JPA是通过什么方法来知道我们是要进行insert还是update呢? 经过测试,JPA对程序调用的save()方法判 ...
- Ubuntu16.04下安装和配置Redis
一.前提条件 需要连接互联网,然后执行sudo apt-get update更新软件包 二.执行安装命令 sudo apt-get install redis-server 执行后如下图所示,我们输 ...
- Java 下一代: 函数式编码风格——Groovy、Scala 和 Clojure 共享的函数结构及其优势
原文地址 本文内容 命令式处理 函数式处理 函数式编程的优势 所有 Java 下一代语言都包括函数式编程结构,让您可以从一个更高的抽象层面来思考问题.然而,语言间术语的不同使得难以看到类似的结构.本期 ...
- 原创:vsphere概念深入系列四:Nic Teaming若干问题
参考文档:http://www.hyper-v.nu/archives/marcve/2013/01/lbfo-hyper-v-switch-qos-and-actual-performance-pa ...
- Promise.then的第二个参数与catch的区别
1.异常捕获 getJSON("/post/1.json").then(function(post) { return getJSON(post.commentURL); }).t ...
- 用 CPI 火焰图分析 Linux 性能问题
https://yq.aliyun.com/articles/465499 用 CPI 火焰图分析 Linux 性能问题 yangoliver 2018-02-11 16:05:53 浏览1076 ...
- 重写$.ajax方法
/*重写Jquery中的ajax 封装壳*/ $(function () { (function ($) { //首先备份下jquery的ajax方法 var _ajax = $.ajax; //重写 ...
- RabbitMQ ——“Hello World”
介绍 RabbitMQ是一个消息实体服务(broker):它接收及转发消息.你可以把它想象成一个邮局:当你把你想要寄送的邮件放进邮箱里时,你能够确信邮局的派送员最终会把你的这封邮局送到这信的收件者手中 ...
- Python 贝叶斯分类
很久的时间没有更新了,一是因为每天加班到比较晚的时间,另外,公司不能上网,回家后就又懒得整理,最近在看机器学习实战的书籍,因此才又决定重新拾起原先的博客! 今天讲的是第三章的贝叶斯分类方法,我们从一个 ...