Description
定义生成一棵树的方式:对于节点i从[1,i-1]随机一个父亲。求这棵树的期望高度
n
≤
24
n\le24
n≤24
Solution
设f[i,j]表示i个节点高度为j的方案数。注意到2的父亲一定是1,我们可以枚举2为根的子树的情况,然后讨论一下能否成为最大值就行了
转移看代码。。
Code
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
typedef long long LL;
const int N=205;
const int r[]={0,1,2,3,3,3,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6};
LL f[N][N],C[N][N]; int MOD;
int read() {
int x=0,v=1; char ch=getchar();
for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):v,ch=getchar());
for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());
return x*v;
}
LL ksm(LL x,LL dep) {
LL res=1; for (;dep;dep>>=1,x=x*x%MOD) {
(dep&1)?(res=res*x%MOD):0;
} return res;
}
void upd(LL &x,LL v) {
x+=v,(x>=MOD)?(x-=MOD):0;
}
int main(void) {
int n=read(); MOD=read();
printf("%d\n", r[n]);
C[0][0]=1;
rep(i,1,n) {
C[i][0]=C[i][i]=1;
rep(j,1,i-1) upd(C[i][j],C[i-1][j]),upd(C[i][j],C[i-1][j-1]);
}
f[1][1]=1;
rep(i,2,n) rep(j,2,i) {
rep(x,1,i-1) {
LL tmp=0;
rep(y,1,j-2) upd(tmp,f[x][y]*f[i-x][j]%MOD);
rep(y,1,j) upd(tmp,f[x][j-1]*f[i-x][y]%MOD);
upd(f[i][j],tmp*C[i-2][x-1]%MOD);
}
}
LL ans=0;
rep(i,1,n) upd(ans,f[n][i]*i%MOD);
rep(i,1,n-1) ans=ans*ksm(i,MOD-2)%MOD;
printf("%lld\n", ans);
return 0;
}