bzoj 5305: [Haoi2018] Apple tree

Description

Solution

The number of solutions for a binary tree with \(n\) points is \(n!\)
The proof is very obvious: the newly added point occupies \(1\) positions, and new \(2\) positions are added, then There is one more position, so the \(i\) point has a \(i\) placement method.
Considering the number of times each edge has been passed, set the size of the subtree to \(size\) , which is \(size*(n -size)\) In
this way, consider the number of times the parent edge of each point is passed, enumerate the size of the subtree,
and then the contribution is the number of solutions in the internal shape of the subtree multiplied by the number of solutions in the external shape. The
internal one is obviously \(size!\) , but the number is still uncertain, so we first determine a tree of size \(i\ ) outside of \(size!*C_{ni}^{size-1}\) , and then put the extra \(n -size-i+1\) put together, the number of solutions is \(\frac{(nj-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;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325027484&siteId=291194637