背景:
开始刷题了?
刷不动啊。
题目传送门:
https://www.luogu.org/problemnew/show/P3978
题意:
求出一棵有
n
n
n个节点的二叉树的叶子节点的期望。
思路:
看起来好像有点复杂。
考虑从暴力入手。
设
f
i
f_i
fi表示有
n
n
n个节点的二叉树的叶子节点的叶子节点的个数。
f
n
=
∑
i
=
0
n
−
1
2
f
i
g
n
−
1
−
i
f_n=\sum_{i=0}^{n-1}2f_{i}g_{n-1-i}
fn=i=0∑n−12fign−1−i
为什么是这样?
枚举左子树的大小
i
i
i,其叶节点的个数就是
f
i
f_{i}
fi,而右子树的大小就是
(
n
−
1
−
i
)
(n-1-i)
(n−1−i),而其生成二叉树的个数为
Catalan number
\text{Catalan number}
Catalan number,记作
g
g
g,那就是
g
n
−
1
−
i
g_{n-1-i}
gn−1−i。
∗
2
*2
∗2是因为左右儿子可以交换。
参考生成函数——OGF学习笔记,我们令
f
1
=
0
,
g
1
=
0
f_{1}=0,g_{1}=0
f1=0,g1=0,因此我们要补的就是一次项,也就是要加上
x
x
x,我们可以写出其生成函数的式子:
F
=
2
x
F
G
+
x
F=2xFG+x
F=2xFG+x
由生成函数——OGF学习笔记
T6
\text{T6}
T6可知
G
G
G的生成函数为
G
(
x
)
=
1
−
1
−
4
x
2
x
G(x)=\frac{1-\sqrt{1-4x}}{2x}
G(x)=2x1−1−4x,带入得:
F
=
2
x
F
1
−
1
−
4
x
2
x
+
x
F
=
x
1
−
4
x
\begin{aligned}F&=2xF\frac{1-\sqrt{1-4x}}{2x}+x\\ F&=\frac{x}{\sqrt{1-4x}}\end{aligned}
FF=2xF2x1−1−4x+x=1−4xx
上面的
x
x
x只是影响第几项,并不影响序列里的值。因此我们先讨论
1
1
−
4
x
\frac{1}{\sqrt{1-4x}}
1−4x1。
和生成函数——OGF学习笔记
T6
\text{T6}
T6类似,我们可化得:
1
1
−
4
x
=
(
1
−
4
x
)
−
1
2
=
∑
k
=
0
∞
2
(
2
k
−
1
)
!
k
!
(
k
−
1
)
!
x
k
\begin{aligned}\frac{1}{\sqrt{1-4x}}&=(1-4x)^{-\frac{1}{2}}\\ &=\sum_{k=0}^{\infty}\frac{2(2k-1)!}{k!(k-1)!}x^k\end{aligned}
1−4x1=(1−4x)−21=k=0∑∞k!(k−1)!2(2k−1)!xk
因为我们只关心在第
n
−
1
n-1
n−1(
x
x
x相当于向右平移一位,
n
n
n代表
n
−
1
n-1
n−1)项的系数,因此:
[
x
n
−
1
]
F
=
2
(
2
(
n
−
1
)
−
1
)
!
(
n
−
1
)
!
(
(
n
−
1
)
−
1
)
!
=
2
(
2
n
−
3
)
!
(
n
−
1
)
!
(
n
−
2
)
!
=
2
C
(
2
n
−
3
n
−
1
)
\begin{aligned}[x^{n-1}]F&=\frac{2(2(n-1)-1)!}{(n-1)!((n-1)-1)!}\\ &=\frac{2(2n-3)!}{(n-1)!(n-2)!}\\ &=2C(_{2n-3}^{n-1})\end{aligned}
[xn−1]F=(n−1)!((n−1)−1)!2(2(n−1)−1)!=(n−1)!(n−2)!2(2n−3)!=2C(2n−3n−1)
这只是叶节点的个数啊,期望怎么求。
那肯定是除以生成树的总个数
g
n
g_{n}
gn啊。
a
n
s
=
2
C
(
2
n
−
3
n
−
1
)
C
(
2
n
n
)
n
+
1
ans=\frac{2C(_{2n-3}^{n-1})}{\frac{C(_{2n}^{n})}{n+1}}
ans=n+1C(2nn)2C(2n−3n−1)
a n s = 2 ( n + 1 ) C ( 2 n − 3 n − 1 ) C ( 2 n n ) ans=\frac{2(n+1)C(_{2n-3}^{n-1})}{C(_{2n}^{n})} ans=C(2nn)2(n+1)C(2n−3n−1)
a
n
s
=
n
(
n
+
1
)
2
(
2
n
−
1
)
ans=\frac{n(n+1)}{2(2n-1)}
ans=2(2n−1)n(n+1)
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
double n;
int main()
{
scanf("%lf",&n);
printf("%.9lf",n*(n+1)/(2*(2*n-1)));
}