@xiaoziyao
2020-11-04T22:05:55.000000Z
字数 2416
阅读 1004
解题报告
P3830 [SHOI2012]随机树解题报告:
期望神仙题。
我们考虑一次对深度为的叶子结点的操作会造成什么影响——减少个深度为的叶子结点,增加两个深度为的叶子结点,总贡献为。
设为个叶子结点的情况下叶子结点平均深度的期望,那么有,解释一下,下面的是叶子结点个数,上面左边的是原来个叶子结点的总深度,为新的叶子结点的贡献。
因为边界是(根结点深度为),因此答案为。
前置知识:正整数的期望公式,即对于正整数随机变量,有
证明:
解释:第一步很显然是期望的定义,第二步是一个差分(因为是正整数),第三步就是拆了一下式子,可以发现因为趋近于无限,所以可以把求和挪过来一位,因此有了第四步(虽然没有可以挪到的式子,但因为时,因此加上可以保持美观),最后相减就可以得到第五个式子了。
设为个叶子结点的情况下,树深度大于等于的概率,那么根据上面的正整数期望公式,我们的答案就是(因为根结点深度为,因此不可能深度等于),边界为。
然后考虑如何求,可以考虑枚举左子树的结点个数,得到。
解释:前面的表示在个叶子结点的树中,左子树有个叶子结点的概率;后面的利用了一种容斥的思想,即左子树深度大于等于或右子树深度大于等于的概率等于它们的概率之和减去它们的概率之积。
然后我们的问题到了怎么求,有一个非常神奇的结论:对于所有的,都有相等,即。
考虑如何证明,我们发现对左子树进行的操作是与右子树无关的,我们把所有操作分成扩展左子树和右子树,那么如果扩展了次且左子树扩展了次,那么右子树扩展了的次一定与左子树无关(子树的根结点也需要进行一次扩展),因此我们需要用一个式子来表达选取这样的扩展方案的方案数:。
通过组合数我们知道了选定哪些操作,而这些操作作用在不同的结点上又是不一样的方案,因此我们还需要计算作用在不同结点上一共有多少种方案。对于左子树,第一次可以作用的结点数为,第二次为,第为,因此左子树方案数为,同理右子树的方案数为。
将选定操作的方案数和作用在不同结点上的方案数相乘就是左子树个叶子结点,右子树个叶子结点的方案:,它与无关,因此所有的情况概率相等。又因为的取值只有种,所以。
故转移方程为,答案为。
#include<stdio.h>
const int maxn=105;
int q,n;
double ans;
double f[maxn][maxn];
int main(){
scanf("%d%d",&q,&n);
if(q==1)
for(int i=2;i<=n;i++)
ans+=2.0/i;
if(q==2){
for(int i=1;i<=n;i++){
f[i][0]=1.0;
for(int j=1;j<i;j++)
for(int k=1;k<i;k++)
f[i][j]+=1.0/(i-1)*(f[k][j-1]+f[i-k][j-1]-f[k][j-1]*f[i-k][j-1]);
}
for(int i=1;i<n;i++)
ans+=f[n][i];
}
printf("%.6lf\n",ans);
return 0;
}