1. 程式人生 > 實用技巧 >18.求組合數 II

18.求組合數 II

上一題是直接預處理出來了這個值是多少,這道題是預處理求值過程中間的一步

根據這個公式,預處理出來fact[i] =i! % mod的結果

然後再用逆元運算,把除法變成乘法

再預處理一個infact[i]

預處理完之後,就可以計算了

因為除以一個數對m取模等於乘以這個數的逆元對m取模

求逆元可以用快速冪,因為1e9 + 7是個質數,可以用費馬小定理

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N = 100010, mod = 1e9 + 7;
 5
ll fact[N], infact[N]; //儲存的都是模上mod的值 6 ll qmi(ll a, ll k, ll p) { 7 ll res = 1; 8 while (k) { 9 if (k & 1) { 10 res = res * a % p; 11 } 12 a = a * a % p; 13 k >>= 1; 14 } 15 return res; 16 } 17 int main() { 18 fact[0] = infact[0
] = 1; //邊界情況,0! = 1 19 for (int i = 1; i < N; i++) { 20 fact[i] = fact[i - 1] * i % mod; 21 infact[i] = infact[i - 1] * qmi(i, mod - 2, mod) % mod; 22 } 23 int n; 24 cin >> n; 25 while (n--) { 26 int a, b; 27 cin >> a >> b; 28 cout << fact[a] * infact[a - b] % mod * infact[b] % mod << endl;
29 } 30 return 0; 31 }