zoukankan      html  css  js  c++  java
  • bzoj 5305: [Haoi2018]苹果树

    Description

    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)!})

    #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;
    }
    
    
  • 相关阅读:
    【git hub使用】
    【struct2 第一天】
    【JSP基础 第一天】
    【Java基础学习 day01】
    网站建设 【Django】 【MTV】
    Python-Json字符串和XML解析
    Python-冒泡和快排
    Python-面向对象编程
    练习-字符串编码
    练习-统计文件中单词数量
  • 原文地址:https://www.cnblogs.com/Yuzao/p/8966346.html
Copyright © 2011-2022 走看看