##Description c++
##Solution $n$ 个点的二叉树的方案数是 $n!$ 证实十分显然:新加入的点占掉了 $1$ 个位置,新加了 $2$ 个位置,那么多出来一个位置,因此第 $i$ 个点有 $i$ 种放法 考虑每条边被通过的次数,设子树大小为 $size$,就是 $size*(n-size)$ 以此考虑每一个点父边被通过的次数,枚举子树大小 而后贡献就是子树内部形态的方案数乘之外部形态的方案数 内部的显然就是 $size!$ , 可是编号还不肯定,因此是 $size!*C_{n-i}^{size-1}$ 外部的咱们先肯定一个大小为 $i$ 的树,再把多出来的 $n-size-i+1$ 个拼上去,方案数为 $\frac{(n-j-1)!}{(i-2)!}$spa
#include<bits/stdc++.h> using namespace std; const int N=2010; int n,mod,c[N][N],Fac[N],w[N][N]; inline int F(int x,int y){ if(y<=0)return 1; return w[x][y]; } int main(){ freopen("pp.in","r",stdin); freopen("pp.out","w",stdout); cin>>n>>mod; for(int i=0;i<=n;i++){ c[i][0]=1; for(int j=1;j<=i;j++)c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod; } Fac[0]=1; for(int i=1;i<=n;i++)Fac[i]=1ll*Fac[i-1]*i%mod; for(int i=1;i<=n;i++){ w[i][0]=1; for(int j=1;j<=n;j++)w[i][j]=1ll*w[i][j-1]*(i+j-2)%mod; } int ans=0; for(int i=2;i<=n;i++) for(int j=n-i+1;j>=1;j--) ans=(ans+1ll*Fac[j]*c[n-i][j-1]%mod*Fac[i]%mod*F(i,n-j-i+1)%mod*(n-j)%mod*j)%mod; cout<<ans<<endl; return 0; }