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\) ...
随机推荐
- Appium基础(二)demo
具体配置,请看上一篇 一.启动Android模拟 Start 打开如下界面:这个过程可能会有些慢,黑屏等等,请耐心等待 二.appium配置 1.点机器人图标 PlatformVersion 选19, ...
- Sift中尺度空间、高斯金字塔、差分金字塔(DOG金字塔)、图像金字塔
转自:https://blog.csdn.net/dcrmg/article/details/52561656 一. 图像金字塔 图像金字塔是一种以多分辨率来解释图像的结构,通过对原始图像进行多尺度像 ...
- 使用mysqlbinlog从二进制日志文件中查询mysql执行过的sql语句 (原)
前提MySQL开启了binlog日志操作1. 查看MySQL是否开启binlog(进mysql操作) mysql> show variables like 'log_bin%'; 2 ...
- QT 添加 lib库
扒自网友文章: 一.添加第三方的头文件 首先,添加头文件 #include "ControlCAN.h" 然后,再将这个头文件放到工程的目录下 二.添加.lib文件 首先,将.l ...
- time_t time()
time_t atime, btime; time(&atime); btime = time(0); 两种方式效果一样.
- MyBatis基础入门《六》Like模糊查询
MyBatis基础入门<六>Like模糊查询 描述: 未改动的文件,不再粘贴出来.项目中SQL的xml映射文件重要标签如下: mapper namespace cache 配置给定命令空间 ...
- python 定义函数 两个文件调用函数
在def_function.py文件里面写 #coding=utf-8 #定义函数 def hello(): print "hello world" 在test.py里面调用 #c ...
- laravel service provider
https://laravel-china.org/articles/6189/laravel-service-provider-detailed-concept https://oomusou.io ...
- linux中安装oracle数据库
1. 执行 ./runInstaller 提示 /tmp 的空间过小执行 mount -o remount,size=1G,noatime /tmp重新设置 /tmp 的大小 2. 安装完成数据库之后 ...
- html2pdf后逐页固定位置盖公章
需要通过NuGet添加Html2Pdf引用 #region 通过Html来生成pdf,测试Html样式 /// <summary> /// 通过Html来生成pdf,测试Html样式 // ...