4001: [TJOI2015]概率论
Time Limit: 10
Sec Memory Limit: 128 MB
Description
为了提高智商,ZJY开始学习概率论。有一天,她想到了这样一个问题:对于一颗随机生成的n个节点的有根二叉树(所以互相不同构的形态等概率出现),它的叶子节点数的期望是多少呢?
判断两棵树是否同构的伪代码如下:
判断两棵树是否同构的伪代码如下:
算法1:bool Check(T1, T2)
Require:两棵树的节点T1, T2
if T1==null || T2==null then
return T1==null && T2==null
else
return Check(T1->leftson, T2->leftson) && Check(T1->rightson, T2->rightson)
end if
Require:两棵树的节点T1, T2
if T1==null || T2==null then
return T1==null && T2==null
else
return Check(T1->leftson, T2->leftson) && Check(T1->rightson, T2->rightson)
end if
Input
输入一个正整数N,代表有根树的结点数
Output
输出这棵树期望的叶子节点数。要求误差小于1×10−9
Sample Input
1
Sample Output
1.000000000
HINT
1⩽N⩽109
Solution
设P(x)表示x个节点的二叉树叶子节点数的期望,fx为x个节点可构成的不同二叉树的数量,sx为x个节点构成的所有不同二叉树的叶子节点的和。由期望的定义可得,P(x)=sxfx。
fx的求法是一个经典的卡塔兰数问题:固定某个点为根节点,设其左子树有a个节点,右子树有b个节点,在此条件下,不同的二叉树的数量等于fafb。而对于fx,a+b=x−1且0⩽a⩽x−1。即:fx=x−1∑i=0fi⋅fx−1−i
我们用相似的方式推导sx的递推式:
固定某个点为根节点,设其左子树有a个节点,右子树有b个节点,我们首先这考虑左子树对sx的贡献,所有不同的左子树的叶子节点的数量和为sa,每种方案都可以和一个右子树结合得到一棵不同形态的二叉树,结合的方案数为fb,所以左子树对sx的贡献为safb。类似地,左右子树的总贡献为safb+fasb。又因为a+b=x,所以:sx=x−1∑i=0(si⋅fx−1−i+fi⋅sx−1−i)=2x−1∑i=0si⋅fx−1−i
参考卡塔兰数通项公式的推导,我们采用母函数计算sx的通项公式。
我们首先确定s0的值,由于s1=2f0s0=1,s2=2s0f1+2s1f0=2,我们发现s0无论取和值都无法满足条件。于是我们大胆猜测,sx的递推式不适用于第一项。这样,s0=0。
根据普通母函数的定义,设:g(x)=∞∑n=0snxn
h(x)=∞∑n=0fnxn
展开,有g(x)=s0+s1x+s2x2+s3x3+...
h(x)=f0+f1x+f2x2+f3x3+...
考虑母函数与递推式的联系:g(x)h(x)=s0f0+(s0f1+s1f0)x+(s2f0+s1f1+s0f2)x2+...
整理,得:g(x)h(x)=0∑i=0sif0−i+(1∑i=0sif1−i)x+(2∑i=0sif2−i)x2+...
根据sx的递推式:xg(x)h(x)=0∑i=0sif0−ix+(1∑i=0sif1−i)x2+(2∑i=0sif2−i)x3+...
2xg(x)h(x)=0+s2x2+s3x3+...
即:2xg(x)h(x)=g(x)−s1x
结合卡塔兰数的推导:{2xg(x)h(x)=g(x)−xxh(x)2=h(x)−1
解得:{g(x)=x√1−4xh(x)=1−√1−4x2x,{g(x)=−x√1−4xh(x)=1+√1−4x2x
不妨令g(x)=x√1−4x=x(1−4x)−12,根据二项式定理:g(x)=x∞∑n=0(−12n)(−4x)n
g(x)=x∞∑n=0(−12)×(−32)×...×(−12−i+1)n!(−4x)n
g(x)=x∞∑n=01×3×...×(2n−1)n!2nxn
g(x)=x∞∑n=0(2n)!n!⋅n!xn
g(x)=x∞∑n=0(2nn)xn
g(x)=∞∑n=1(2n−2n−1)xn
所以sx=(2x+2x+1)
得到了sx的通项公式。我们可以一眼看出P(x)=x2+x4x−2。
代码一分钟,公式一下午!
:(
倘若真的在考场上,我会打表找规律。
回复删除