bzoj 5305: [Haoi2018]蘋果樹

##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;
}
相關文章
相關標籤/搜索