EagleBear2002 的博客

这里必须根绝一切犹豫,这里任何怯懦都无济于事

P3978 [TJOI2015] 概率论

题目描述

为了提高智商,ZJY 开始学习概率论。有一天,她想到了这样一个问题:对于一棵随机生成的 n(n109) 个结点的有根二叉树(所有互相不同构的形态等概率出现),它的叶子节点数的期望是多少呢?

判断两棵树是否同构的伪代码如下:

算法 1Check(T1,T2)1Require:  两棵树的节点T1,T22if  T1=null or T2=null then 3return  T1=null and T2=null4else5return Check(T1leftson,T2leftson) and Check(T1rightson,T2rightson)6endif

输入格式

输入一个正整数 n,表示有根树的结点数。

输出格式

输出这棵树期望的叶子节点数,要求误差小于 109

输入输出样例 #1

输入 #1

1
1

输出 #1

1
1.000000000

输入输出样例 #2

输入 #2

1
3

输出 #2

1
1.200000000

说明/提示

数据范围

对于 30% 的数据,1n10

对于 70% 的数据,1n100

对于 100% 的数据,1n109

题解

f(n) 表示 n 个点的二叉树个数;g(n) 表示 n 个点的所有 f(n) 棵二叉树的叶节点总数。

打表如下:

n 1 2 3 4 5 ...
fn 1 2 5 14 42 ...
gn 1 2 6 20 70 ...

发现规律:g(n)=nf(n1)。证明很简单:

  • 对于每棵 n 个点的二叉树,如果里面有 k 个叶节点,那么我们分别把这 k 个叶子删去会得到 kn1 个点的二叉树;
  • 而每棵 n1 个点的二叉树恰好有 n 个位置可以悬挂一个新的叶子,所以每棵 n1 个点的二叉树被得到了 n 次;
  • 综上,我们即可得出结论:所有 n 个点的二叉树的叶子个数和等于 n1 个点的二叉树个数 ×n

那么我们只需要求出 f 即可。而 f 的递推式可以通过枚举左子树结点个数得到:

f(n)=i=1n1f(i)f(ni1)

边界是 f(1)=1

该递推式显然是 Catalan 数列(其实一看那个 [1,2,5,14,42] 就应该知道,滑稽)。于是答案即为

g(n)f(n)=nf(n1)f(n)

代入卡特兰数的通项公式 fn=C2nnn+1 很容易就得到上式等于 n(n+1)2(2n1)