1. 程式人生 > >LOJ6044 「雅禮集訓 2017 Day8」共

LOJ6044 「雅禮集訓 2017 Day8」共

標籤:數論,組合數學

題目

題目傳送門

這裡寫圖片描述

分析

2018年的第一道題,RP++

5分——手玩樣例puts(“12”);
20分——F[i][j]表示一棵i+j個節點的有根樹,其中i個節點深度為奇數,j個節點深度為偶數的方案數,然後不停列舉除根以外,編號最小的點所在子樹情況進行轉移
40分——用S(N,M)表示左邊N個點,右邊M個點的完全二分圖生成樹個數,答案就是S(K,N-K)*C(N-1,K-1)
100分——觀察法:S(N,M)=NM1MN1,套用40分的公式得出答案,本題複雜度瓶頸在於求組合數

code

#include<iostream>
#include<cstdio>
#include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> #define ll long long #define rep(i,a,b) for(ll i=a;i<=b;i++) #define dep(i,a,b) for(ll i=a;i>=b;i--) #define mem(x,num) memset(x,num,sizeof x) #define reg(x) for(int i=last[x];i;i=e[i].next) using namespace std; inline ll read
() { ll f=1,x=0;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } ll n,k,p,ans; ll inv(ll a){ return a==1?1:(ll)(p-p/a)*inv(p%a)%p; } ll C(ll n,ll m){ if(m<0||n<m)return
0;if(m>n-m)m=n-m; ll up=1,down=1; rep(i,0,m-1){up=up*(n-i)%p;down=down*(i+1)%p;} return up*inv(down)%p; } ll qpow(ll a,ll b){ ll re=1; while(b){ if(b&1)re=(re*a)%p; a=a*a%p; b>>=1; } return re%p; } int main() { n=read(),k=read(),p=read(); ans=C(n-1,k-1)%p;ans=ans*qpow(k,n-k-1)%p;ans=qpow(n-k,k-1)*ans%p; cout<<ans<<endl; return 0; }