洛谷P4430小猴打架
思路:
求
n
n
n个结点,通过不同的连接方式生成的树有多少种。
通过Prufer序列,
n
n
n个结点不同的生成树有
n
n
−
2
n^{n-2}
nn−2种。又因为这
n
−
1
n-1
n−1条边可以以任意顺序连上,所以乘上这
n
−
1
n-1
n−1条边全排列的数量,即
(
n
−
1
)
!
n
n
−
2
(n-1)!n^{n-2}
(n−1)!nn−2种。
代码:
#include<bits/stdc++.h>
#define pii pair<int,int>
#define int long long
#define cl(x,y) memset(x,y,sizeof(x))
#define loop(x,y,z) for(x=y;x<=z;x++)
#define reve(x,y,z) for(x=y;x>=z;x--)
#define ct cerr<<"Time elapsed:"<<1.0*clock()/CLOCKS_PER_SEC<<"s.\n";
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define lson x<<1,l,mid
#define rson x<<1|1,mid+1,r
#define INF 1e18
const int N=1e6+10;
const int mod=9999991;
const int inf=0x3f3f3f3f;
const double eps=1e-8;
const double pi=acos(-1);
using namespace std;
int qpow(int a,int b)
{
a%=mod;
int ans=1;
while(b)
{
if(b&1)
ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n,i;
cin>>n;
if(n==1)
{
cout<<0<<endl;
return 0;
}
int ans=qpow(n,n-2)%mod;
for(i=1;i<n;i++)
ans=ans*i%mod;
cout<<ans<<endl;
return 0;
}