Secret Project Gym - 101972(组合数大数+思维)

题目:有 n 个人,x把锁,(每个人有y把钥匙),要求最少有 m 个人在场才能打开这所有的x把锁,问 x y 的最小值分别是多少。

分析:

1、公式:https://blog.csdn.net/SunMoonVocano/article/details/84137160

2、组合数大数求解,因为涉及到模运算,所以需要用到乘法逆元;也即边打阶乘的表,边求阶乘关于mod的逆元。

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const ll mod = 1e9 + 7;
 5 const int maxn = 1e5 + 10;
 6 ll fi[maxn], ni[maxn];
 7 
 8 ll pow(ll a, ll n, ll mod)
 9 {
10     ll ans = 1;
11     while (n > 0)
12     {
13         if (n & 1)
14             ans = ans * a % mod;
15         a = a * a % mod;
16         n >>= 1;
17     }
18     return ans % mod;
19 }
20 
21 void make()
22 {
23     fi[0] = fi[1] = 1;
24     ni[0] = 1;
25     for (int i = 1; i < maxn; i++)
26     {
27         fi[i] = fi[i - 1] * i % mod;
28         ni[i] = pow(fi[i], mod - 2, mod);
29     }
30 }
31 
32 int main()
33 {
34     int T; cin >> T;
35     make();
36     while (T--)
37     {
38         ll n, m; cin >> n >> m;
39         printf("%lld %lld\n", fi[n] * ni[m - 1] % mod * ni[n - m + 1] % mod, fi[n - 1] * ni[m - 1] % mod * ni[n - m] % mod);
40     }
41 }

 

posted @ 2019-10-11 22:37  滚烫的青春  阅读(176)  评论(0编辑  收藏  举报