Codeforces 995F Cowmpany Cowmpensation - 组合数学
很容易地能得到$O(nD)$的动态规划:设$f[i][j]$表示$i$号点标为$j$在它的子树内的方案数。
写写它的转移方程:$f[i][j] = \prod_{s \in Son(i)}\sum_{k = 1}^{j} f[s][k]$。
设$g[i][j]=\sum_{k = 1}^{j}f[i][k]$,那么转移方程就能写成:$f[i][j] = \prod_{s \in Son(i)} g[s][j]$。
感觉很优美,考虑它有怎样的性质。
引理1 $f[i][j]$可以看成是关于$j$的多项式,其次数是$i$的子树大小减1,$g[i][j]$可以看成是关于$j$的多项式,其次数是$i$的子树大小。
证明 考虑用归纳法。
考虑叶节点,它的$f[i][j] = 1, g[i][j] = j$,因此对于叶节点成立。
然后前一部分可以证明了。对于后一部分,因为$g[i]$是$f[i]$的前缀和函数,因此次数恰好比它大1(用差分)。
然后后面的做法就很傻逼了。记录每个点$f, g$函数的在$1,\cdots,n + 1$处的取值,暴力计算。最后用逐差法插值,求$f[1][D]$。
表示切完后才发现是Div 1。要不看标题,真以为是Div 2.
Code
/**
* Codeforces
* Problem#995F
* Accepted
* Time: 140ms
* Memory: 35400k
*/
#include <iostream>
#include <cstdlib>
#include <cstdio>
using namespace std;
typedef bool boolean; const int N = , M = 1e9 + ; void exgcd(int a, int b, int& x, int& y) {
if (!b)
x = , y = ;
else {
exgcd(b, a % b, y, x);
y -= (a / b) * x;
}
} int inv(int a, int n) {
int x, y;
exgcd(a, n, x, y);
return (x < ) ? (x + n) : (x);
} int n, D;
int fa[N];
int f[N][N]; int add(int a, int b) {
a = a + b;
if (a >= M)
a -= M;
if (a < )
a += M;
return a;
} inline void init() {
scanf("%d%d", &n, &D);
for (int i = ; i <= n; i++)
scanf("%d", fa + i);
} inline void solve() {
for (int i = ; i <= n; i++)
for (int j = ; j <= n + ; j++)
f[i][j] = ;
for (int i = n; i; i--) {
for (int j = ; j <= n + ; j++)
f[i][j] = add(f[i][j], f[i][j - ]);
if (i > )
for (int j = ; j <= n + ; j++)
f[fa[i]][j] = f[fa[i]][j] * 1ll * f[i][j] % M;
}
for (int i = ; i <= n + ; i++)
for (int j = ; j <= n - i + ; j++)
f[i][j] = add(f[i - ][j + ], -f[i - ][j]);
int ans = , C = ;
for (int i = ; i <= n + && i <= D; i++) {
ans = add(ans, C * 1ll * f[i][] % M);
C = C * 1ll * (D - i) % M * inv(i, M) % M;
}
printf("%d\n", ans);
} int main() {
init();
solve();
return ;
}
Codeforces 995F Cowmpany Cowmpensation - 组合数学的更多相关文章
- codeforces 955F Cowmpany Cowmpensation 树上DP+多项式插值
给一个树,每个点的权值为正整数,且不能超过自己的父节点,根节点的最高权值不超过D 问一共有多少种分配工资的方式? 题解: A immediate simple observation is that ...
- Codeforces F. Cowmpany Cowmpensation
Description 有一棵树,现在要给每个节点赋一个在1到D之间的权值,问有多少种方案满足任意一个节点的权值都不大于其父亲的权值. n<=3000,D<=1e9 题面 Solution ...
- 【CF995F】 Cowmpany Cowmpensation
CF995F Cowmpany Cowmpensation Solution 这道题目可以看出我的代码能力是有多渣(代码能力严重退化) 我们先考虑dp,很容易写出方程: 设\(f_{i,j}\)表示以 ...
- 【CF995F】Cowmpany Cowmpensation(动态规划,拉格朗日插值)
[CF995F]Cowmpany Cowmpensation(多项式插值) 题面 洛谷 CF 题解 我们假装结果是一个关于\(D\)的\(n\)次多项式, 那么,先\(dp\)暴力求解颜色数为\(0. ...
- 【CF995F】Cowmpany Cowmpensation
[CF995F]Cowmpany Cowmpensation 题面 树形结构,\(n\)个点,给每个节点分配工资\([1,d]\),子节点不能超过父亲节点的工资,问有多少种分配方案 其中\(n\leq ...
- Codeforces 40E Number Table - 组合数学
题目传送门 传送门I 传送门II 题目大意 给定一个$n\times m$的网格,每个格子上要么填$1$,要么填$-1$,有$k$个位置上的数是已经填好的,其他位置都是空的.问有多少种填法使得任意一行 ...
- Codeforces 37D Lesson Timetable - 组合数学 - 动态规划
题目传送门 神奇的门I 神奇的门II 题目大意 有$n$组学生要上课2次课,有$m$个教室,编号为$1$到$m$.要确定有多少种不同的安排上课的教室的方案(每组学生都是本质不同的),使得它们满足: 每 ...
- Codeforces 711D Directed Roads - 组合数学
ZS the Coder and Chris the Baboon has explored Udayland for quite some time. They realize that it co ...
- [CF995F]Cowmpany Cowmpensation
codeforces description 一棵\(n\)个节点的树,给每个节点标一个\([1,m]\)之间的编号,要求儿子的权值不大于父亲权值.求方案数.\(n\le3000,n\le10^9\) ...
随机推荐
- cocos2d-x C++ iOS工程集成第三方支付宝支付功能
一.在支付宝开放平台下载支付宝SDK(https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.WWgVz8&tr ...
- (已解决)Xcode 运行报错: clang: error: unknown argument: '-websockets'
报错内容: 解决办法:
- Linux(Centos)服务器配置node项目
以阿里云服务器,CentOS系统为例 上一节已经提到怎么安装nodejs,以下是以vue项目为例 步骤: (1)首先安装vue脚手架@vue/cli, 官网参考 vue-cli3.x [root@lu ...
- 008-副文本编辑器UEditor
<!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...
- docker-php-ext-install.md(https://gist.github.com/giansalex/2776a4206666d940d014792ab4700d80)
```bash RUN apt update RUN apt upgrade -y RUN apt install -y apt-utils RUN a2enmod rewrite RUN apt i ...
- Day7 错误和异常
一.异常 1.异常基础 1.为了让我们的代码在出现异常的时候,整个项目依然是可以正常运行的,所以我们引入了异常处理机制! 2.在编程过程中为了增加友好性,在程序出现bug时一般不会将错误信息显示给用户 ...
- HTML5语义化元素
语义化元素:有意义的元素. 对语义化的理解: 正确的标签做正确的事情: HTML5语义化元素让页面内容结构化清晰: 便于开发人员阅读,理解,维护: 搜索引擎爬虫可以依赖语义化元素来确定上下文和每个关键 ...
- Spring cglib 初始化 ExceptionInInitializerError,new Enhancer() 异常
解决办法:更换 spring-cglib-repack-*.*.jar 包 java.lang.ExceptionInInitializerError at org.springframework.a ...
- JDK历史版本下载地址
JDK历史版本下载地址: http://www.oracle.com/technetwork/java/archive-139210.html -startupplugins/org.eclipse. ...
- linux常用命令:touch 命令
linux的touch命令不常用,一般在使用make的时候可能会用到,用来修改文件时间戳,或者新建一个不存在的文件. 1.命令格式: touch [选项]... 文件... 2.命令参数: -a ...