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 }