Problem
题目描述
概率论(Ⅱ)
(probability.in/probability.out/probability.cpp 3s,128m)
为了提高智商,NamelessOIer
开始学习概率论。有一天,本菜鸡想到了这样一个问题:
对于一棵随机生成的(n)个结点的有根(k)叉树(所有互相不同构的形态等概率出现),它的叶子节点数的期望是多少呢?
因为NamelessOIer
不喜欢小数,你只需要告诉本菜鸡答案对(1e9+7)取模的结果
输入格式
第一行输入一个正整数(T),表示有(T)组数据
接下来(T)行输入两个正整数(k,n)
输出格式
共(T)行,每行输出这棵树期望的叶子节点数,答案对(1e9+7)取模
如果取模后没有意义(比如(frac{1}{3}mod3)就没有意义),请输出(-1)
输入输出样例
输入样例
4
2 2
2 3
3 3
100 10000
输出样例
1
400000004
250000003
186761855
样例解释
前三组期望分别是(1),(frac{6}{5}),(frac{5}{4})
数据范围
对于10%的数据,(k=2,1le nle 10^3,Tle 100)
对于20%的数据,(k=2,1le nle 10^9,Tle10^6)
对于30%的数据,(kle4,1le nle 10^9,Tle10^6)
对于50%的数据,(kle10,1le nle 10^3,Tle10)
对于70%的数据,(2leq k, nleq 10^7,Tleq10^7)且(k*nle10^7)
对于100%的数据,(2leq k, nleq 10^7,Tleq10^7)且至多有(5)组数据满足(k*nge10^7)
Solution
大佬们秒题愉快吗?
这里讲一下本菜鸡的几种做法
Algorithm 1
枚举,期望得分(0pts)
怎么可能这么水
Algorithm 2
求出(n)个节点的(k)叉树个数(a_n)
再求出所有(n)个节点的(k)叉树的叶子节点数(b_n)
写出递推式
复杂度(O(n^k))
期望得分(10pts)
Algorithm 3
考虑(k=2)的情况
这不是BZOJ
原题吗.jpg
设(f(x))是(n)个点的二叉树个数的OGF
(g(x))是(n)个点的所有二叉树的叶节点的个数的OGF
显然有
解得
然后广义二项式定理
展开得
所以答案就是
当然,如果注意到
并且知道二叉树个数就是Catalan Number
就可以跳过广义二项式定理
期望得分(20pts)
Algorithm 4
写出OGF
(应该也许大概可能没写错吧)
如果知道怎么求解三次和四次方程
可以像Algorithm 3
中一样
但是其实是出来坑人的
因为看起来就很恶心
我自己都没有算
有人这么算了吗?
期望得分(30pts)
Algorithm 5
Catalan Number
除了表示(n)个点的二叉树个数
还表示(n)对括号的合法括号序列
还表示在平面直角坐标系上从((0,0))向右或向上走到((n,n)),不越过(y=x)的方案
最后一种是可以(O(n^2))递推的
那么推广到(k)叉树
通过人类智慧可以知道
这相当于在平面直角坐标系上从((0,0))向右或向上走到(((k-1)n,n)),不越过((k-1)y=x)的方案
这玩意儿叫做Fuss-Catalan Number
至于为什么相等
可以考虑画个图
证明递推式相等
即
可以看见路径与(BO,CF,DG,EH)交出了(k)段
即(O ightarrow I),(K ightarrow C),(D ightarrow D),(E ightarrow E)
每一段是个子问题
方案数相乘
就得出上面的递推式
(k)叉树的递推式显然就是这个
初始的(a_0=1)都一样
所以相等
所以可以(O(kn^2))递推出(n)个点的(k)叉树的个数
那么另外一个序列怎么办?
在Algorithm 3
中
答案是(frac{na_{n-1}}{a_n})
那么某个节点是叶节点的概率就是(frac{a_{n-1}}{a_n})
多妙啊
其实很简单
对于有(n)个节点的二叉树
给节点编个号
就有(n!*a_n)种
那么(n-1)个节点二叉树就有((n-1)!*a_{n-1})个
因为每个(n-1)个节点的二叉树有(n)个位置可以增加节点
所以新加一个叶子节点的方案有(n*(n-1)!*a_{n-1})种
所以一个节点是叶子的概率是(frac{n*(n-1)!*a_{n-1}}{n!*a_n}=frac{a_{n-1}}{a_n})
期望就是(frac{n*a_{n-1}}{a_n})
推广到(k)叉
(n)个节点的(k)叉树有(kn-(n-1))个位置(就是把每个点的(k)条边算上再减去已经有的(n-1)条)
最后算出期望就是(frac{[k*(n-1)-n+2]*a_{n-1}}{a_n})
加上Algorithm 4
期望得分(50pts)
Algorithm 6
所以现在的问题变成这样了
已知(f(x)=xf^k(x)+1)
求([x^n]f(x))
设(h(x)=f(x)-1)
所以(h(x)=x(h(x)+1)^k)
由拉格朗日反演
知道
若(G(F(x))=x)
那么([x^n]f(x)=frac{1}{n}[x^{-1}]frac{1}{G^n(x)}=frac{1}{n}[x^{n-1}](frac{x}{G(x)})^n~~(n eq0))
所以令(frac{x}{f^{-1}(x)}=R(x))即(f(x)=xR(f(x)))
则有([x^n]f(x)=frac{1}{n}[x^{n-1}]R^n(x)~~(n eq 0))
所以([x^n]f(x)=[x^n]h(x)=frac{1}{n}[x^{n-1}]((x+1)^k)^n=frac{1}{n}inom{nk}{n-1}~~(n eq 0))
化简得到最后答案为(frac{[k(n-1)]![(k-1)*n+1]!n}{[(k-1)(n-1)]!(kn)!})
然后就可以算了
期望得分(70pts)
Algorithm 7
那么输出(-1)是什么鬼?
注意当(k,n)比较大时分子分母可能是(10^9+7)的倍数
不能直接求逆计算
要开两个变量记录上下分别可以约掉几个(10^9+7)
分子有剩输出(0)
分母有剩输出(-1)
否则就输出约掉后的答案
期望得分(100pts)
Code
写在最后
其实还想过一些奇怪的加强
但是我太懒了
不想写太长的代码
所以就放弃了
还有就是
虽然好像和我关系不大
但是我还是要吟诗一首
高考改革大砍刀,
砍完竞赛砍自招。
旧时清北堂前燕,
飞入寻常211。
新年快乐!