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 }
原文地址:https://www.cnblogs.com/fx1998/p/13458868.html