牛客網國慶集訓派對Day3 H-Travel(計數問題)
阿新 • • 發佈:2018-12-13
思路來源
題解
因為這m次旅遊互不相干,所以在這n-1條邊裡選m-1條邊將其割斷,將原樹劃分為m塊即可。
總方案數考慮順序,取這m塊的全排列即可。
由於原圖是一棵樹,顯然與怎麼連無關,所以輸入部分多餘。
心得
學了盧卡斯定理之後,總想用盧卡斯,實際上用不到。
這裡C(n,m)用原公式處理一下(n!)*(m!)*((n-m)!))的逆元即可,
n,m1e5;初始化處理階乘,費馬小定理解決逆元。
程式碼
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <cmath> #include <set> #include <map> #include <vector> #include <stack> #include <queue> #include <functional> const double INF=0x3f3f3f3f; const int maxn=1e5+10; const int mod=1e9+7; const int MOD=998244353; const double eps=1e-7; typedef long long ll; #define vi vector<int> #define si set<int> #define pii pair<double,int> #define pi acos(-1.0) #define pb push_back #define mp make_pair #define lowbit(x) (x&(-x)) #define sci(x) scanf("%d",&(x)) #define scll(x) scanf("%lld",&(x)) #define sclf(x) scanf("%lf",&(x)) #define pri(x) printf("%d",(x)) #define rep(i,j,k) for(int i=j;i<=k;++i) #define per(i,j,k) for(int i=j;i>=k;--i) #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; ll jc[maxn]; void init()//預處理階乘 { jc[0]=1,jc[1]=1; rep(i,2,maxn) { jc[i]=jc[i-1]*i; if(jc[i]>=mod)jc[i]%=mod; } } ll modpow(ll x,ll n) { ll res=1; while(n) { if(n&1)res*=x; if(res>=mod)res%=mod; x*=x; if(x>=mod)x%=mod; n>>=1; } return res; } ll c(ll n,ll m) { return jc[n]*modpow(jc[m]*jc[n-m]%mod,mod-2)%mod; } int main() { ll t,n,m; init(); scll(t); while(t--) { scll(n),scll(m); int a,b; rep(i,0,n-2)sci(a),sci(b); printf("%lld\n",c(n-1,m-1)*jc[m]%mod); } return 0; }