luogu P3978 [TJOI2015]概率论

背景:

开始刷题了?
刷不动啊。

题目传送门:

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=0n12fign1i

为什么是这样?
枚举左子树的大小 i i i,其叶节点的个数就是 f i f_{i} fi,而右子树的大小就是 ( n − 1 − i ) (n-1-i) (n1i),而其生成二叉树的个数为 Catalan number \text{Catalan number} Catalan number,记作 g g g,那就是 g n − 1 − i g_{n-1-i} gn1i
∗ 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)=2x114x ,带入得:
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=2xF2x114x +x=14x x

上面的 x x x只是影响第几项,并不影响序列里的值。因此我们先讨论 1 1 − 4 x \frac{1}{\sqrt{1-4x}} 14x 1
生成函数——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} 14x 1=(14x)21=k=0k!(k1)!2(2k1)!xk

因为我们只关心在第 n − 1 n-1 n1 x x x相当于向右平移一位, n n n代表 n − 1 n-1 n1)项的系数,因此:
[ 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} [xn1]F=(n1)!((n1)1)!2(2(n1)1)!=(n1)!(n2)!2(2n3)!=2C(2n3n1)

这只是叶节点的个数啊,期望怎么求。
那肯定是除以生成树的总个数 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(2n3n1)

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(2n3n1)

a n s = n ( n + 1 ) 2 ( 2 n − 1 ) ans=\frac{n(n+1)}{2(2n-1)} ans=2(2n1)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)));
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值