Kattis - heapsoffun Heaps of Fun (概率密度函数+dp)
题意:有一棵含有n个结点(n<=300)的根树,树上每个结点上的权值是从[0,ai](ai<=1e9)区间内随机的一个实数,问这棵树能形成一个最小堆的概率。
由于结点取值范围是1e9而且是实数,所以枚举权值dp自然是行不通的了,但可以从函数的角度上考虑。
首先需要了解两个概念:
CDF:分布函数,记为F(x),表示函数F的取值小于等于x的概率。
PDF:概率密度函数,记为f(x),是F(x)的导数,反之,F(x)是f(x)在区间(-∞,x]上的积分。由于本题所有的取值都是从0开始的,因此也可以表示在区间[0,x]上的积分。
那么答案就是根节点rt所对应的CDF的上界Frt(+∞)。
我们记fu(x)为结点u的取值的PDF,Fu(x)为其CDF,那么对于每个叶子结点u来说:
$f_u(x)=\left\{\begin{matrix}\begin{aligned}&\frac{1}{a[u]},0\leqslant x\leqslant a[u]\\&0,others\end{aligned}\end{matrix}\right.,F_u(x)=\int_{0}^{x}f_u(t)dt=\left\{\begin{matrix}\begin{aligned}&\frac{1}{a[u]}x,0\leqslant x\leqslant a[u]\\&1,x>a[u]\end{aligned}\end{matrix}\right.$
那么有了子结点的PDF和CDF,如何去求父结点的PDF和CDF呢?
首先我们要算出每个子结点的取值大于x的概率,因为如果结点u的某个取值x是合法的,那么它的所有子节点的取值都必须大于x。既然Fu(x)表示结点u取值小于等于x的概率,那么取值大于x的概率呢?是1-Fu(x)吗?No!这个公式只适用于叶子结点,因为这里的Fu(x)表示的是“该结点所在子树满足最小堆性质且该结点的值小于等于x的概率”,因此Fu的上界不一定为1,也就是说x的所有取值的概率之和不一定为1。那么应该如何计算呢?
设ub[u]表示结点u及子树下的所有结点的最小的a,那么显然结点u的取值不能超过ub[u],即ub[u]是结点u取值的上界。
所以,正确的计算方法是结点u取值大于x的概率$G_u(x)=\left\{\begin{matrix}\begin{aligned}&F_u(ub[u])-F_u(x),0\leqslant x\leqslant ub[u]\\&0,x>ub[u]\end{aligned}\end{matrix}\right.$
有了子结点的G,就可以求父结点的f了,通过概率计算公式可得:
$f_u(x)=\frac{1}{a[u]}\prod\limits_{fa[v]=u}G_v(x)$
然后对fu(x)积分可以得到Fu(x),然后又可以求出Gu(x),之后就可以继续往父结点递推了。最终答案就是根节点的G(x)的常数项。
复杂度$O(n^3)$
代码如下:(为了方便,代码中每个结点最后保存的函数是G(x))
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=+,mod=1e9+;
int hd[N],ne,rt,a[N],n,ub[N];
struct E {int v,nxt;} e[N];
void addedge(int u,int v) {e[ne]= {v,hd[u]},hd[u]=ne++;}
int Pow(int x,int p) {
int ret=;
for(; p; p>>=,x=(ll)x*x%mod)if(p&)ret=(ll)ret*x%mod;
return ret;
}
int inv(int x) {return Pow(x,mod-);}
typedef vector<int> Poly;
Poly F[N];
Poly operator*(Poly& a,Poly& b) {
Poly c(a.size()+b.size()-,);
for(int i=; i<a.size(); ++i)
for(int j=; j<b.size(); ++j)
c[i+j]=(c[i+j]+(ll)a[i]*b[j])%mod;
return c;
}
Poly itg(Poly& a) {
Poly c(a.size()+,);
for(int i=; i<a.size(); ++i)c[i+]=(ll)a[i]*inv(i+)%mod;
return c;
}
int eval(Poly& a,int x) {
int ret=;
for(int i=a.size()-; i>=; --i)ret=((ll)ret*x+a[i])%mod;
return ret;
}
void dfs(int u) {
ub[u]=a[u],F[u].push_back(inv(a[u]));
for(int i=hd[u]; ~i; i=e[i].nxt) {
int v=e[i].v;
dfs(v),ub[u]=min(ub[u],ub[v]),F[u]=F[u]*F[v];
}
F[u]=itg(F[u]),F[u][]=eval(F[u],ub[u]);
for(int i=; i<F[u].size(); ++i)F[u][i]=-F[u][i];
}
int main() {
memset(hd,-,sizeof hd),ne=;
scanf("%d",&n);
for(int i=,f; i<=n; ++i) {
scanf("%d%d",&a[i],&f);
if(f)addedge(f,i);
else rt=i;
}
dfs(rt);
printf("%d\n",(F[rt][]+mod)%mod);
return ;
}
Kattis - heapsoffun Heaps of Fun (概率密度函数+dp)的更多相关文章
- LOJ2267 SDOI2017 龙与地下城 FFT、概率密度函数、Simpson
传送门 概率论神仙题-- 首先一个暴力做法是设\(f_{i,j}\)表示前\(i\)个骰子摇出点数和为\(j\)的概率,不难发现DP的过程是一个多项式快速幂,FFT优化可以做到\(O(XYlog(XY ...
- 【BZOJ-1419】Red is good 概率期望DP
1419: Red is good Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 660 Solved: 257[Submit][Status][Di ...
- rvs产生服从指定分布的随机数 pdf概率密度函数 cdf累计分布函数 ppf 分位点函数
统计工作中几个常用用法在python统计函数库scipy.stats的使用范例. 正态分布以正态分布的常见需求为例了解scipy.stats的基本使用方法. 1.生成服从指定分布的随机数 norm.r ...
- 高斯分布(Gaussian Distribution)的概率密度函数(probability density function)
高斯分布(Gaussian Distribution)的概率密度函数(probability density function) 对应于numpy中: numpy.random.normal(loc= ...
- 【bzoj4832】[Lydsy2017年4月月赛]抵制克苏恩 概率期望dp
题目描述 你分别有a.b.c个血量为1.2.3的奴隶主,假设英雄血量无限,问:如果对面下出一个K点攻击力的克苏恩,你的英雄期望会受到到多少伤害. 输入 输入包含多局游戏. 第一行包含一个整数 T (T ...
- 【loj6191】「美团 CodeM 复赛」配对游戏 概率期望dp
题目描述 n次向一个栈中加入0或1中随机1个,如果一次加入0时栈顶元素为1,则将这两个元素弹栈.问最终栈中元素个数的期望是多少. 输入 一行一个正整数 n . 输出 一行一个实数,表示期望剩下的人数, ...
- 函数的光滑化或正则化 卷积 应用 两个统计独立变量X与Y的和的概率密度函数是X与Y的概率密度函数的卷积
http://graphics.stanford.edu/courses/cs178/applets/convolution.html Convolution is an operation on t ...
- BZOJ_3566_[SHOI2014]概率充电器_概率+树形DP
BZOJ_3566_[SHOI2014]概率充电器_概率+树形DP Description 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品——概率充电器: “采用全新纳米级加工技 ...
- Codeforces - 1264C - Beautiful Mirrors with queries - 概率期望dp
一道挺难的概率期望dp,花了很长时间才学会div2的E怎么做,但这道题是另一种设法. https://codeforces.com/contest/1264/problem/C 要设为 \(dp_i\ ...
随机推荐
- Debian系统软件安装
查看已安装软件 dpkg -l | grep -i name apt-get remove name 建议用root安装,有一些工具,使用非root用户安装后,仍然不识别命令,可能跟权限有关. net ...
- Django模板系统-母板和继承
母板和继承 母版 html页面,提取多个页面的公共部分 定义多个block块,需要让子页面进行填充 <head> {% block page-css %} {% endblock %} & ...
- P1820 【寻找AP数】
超级题目链接 这题程序实现其实并不难,难的是数学的思想及证明,这在真正的比赛考场上其实是不容易想到的 去年的年赛题目也是在往更难的数学思想上靠拢,并不是一味的编程,需要一定的数学基础 这个..数学性质 ...
- aliyun挂载oss
配置 oss 挂载 阿里云 ecs 按照ossfs工具:yum install http://gosspublic.alicdn.com/ossfs/ossfs_1.80.5_centos6.5_x8 ...
- 用ufile和S3代替hdfs存储数据
一,添加ufile需在配置中添加: core-site.xml添加如下配置:<property><name>fs.ufile.impl</name><valu ...
- Eclipse myeclipse下配置HanLP的教程
一.说明 博主的配置 1:window10 2:myeclipse 3:jdk1.8 备注:文章分享自贾继康的博客,博客使用的hanlp是1.6.8的版本.大家可以去下载最新的1.7版本了,也比较推荐 ...
- Redis 以及 Python操作Redis
Redis Redis是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis有以下特点: -- Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可 ...
- AppCan模拟器调试
来源: 1, 页面CSS调试 2, JS调试 3, 插件请打包后手机调试 4, 打开另一个页面示例: appcan.button("#myBtn", "ani-uct&q ...
- 阻塞I/O、非阻塞I/O和I/O多路复用、怎样理解阻塞非阻塞与同步异步的区别?
“阻塞”与"非阻塞"与"同步"与“异步"不能简单的从字面理解,提供一个从分布式系统角度的回答.1.同步与异步 同步和异步关注的是消息通信机制 (syn ...
- SG函数和SG定理(Sprague_Grundy)
一.必胜点和必败点的概念 P点:必败点,换而言之,就是谁处于此位置,则在双方操作正确的情况下必败. N点:必胜点,处于此情况下,双方操作均正确的情况下必胜. 必胜点和必败点的性质: ...