fork download
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. typedef long long ll;
  5. // nCk = n! / [(n - k)! * k!]
  6.  
  7. // Cách tính nCk đã giới thiệu ở buổi trước:
  8. // - Áp dụng khi bài có nhiều truy vấn nCk
  9. // - Do phải khai báo 2 mảng để lưu nên áp dụng được cho những bài có giới hạn đủ để đặt mảng
  10. // - Độ phức tạp:
  11. // + precompute: tính 2 mảng fact[], inv_fact[]: O(n)
  12. // + tính nCk: O(1)
  13.  
  14. // Cách tính thứ 2:
  15. // - Độ phức tạp O(k) cho mỗi truy vấn nCk
  16. // - Áp dụng cho trường hợp n lớn, k nhỏ (n <= 10^9, k <= 10^6)
  17.  
  18. const int MOD = 1e9 + 7;
  19.  
  20. ll binpow(ll a, ll b) {
  21. ll ans = 1;
  22. for (; b > 0; b >>= 1) {
  23. if (b & 1) ans = ans * a % MOD;
  24. a = a * a % MOD;
  25. }
  26. return ans;
  27. }
  28.  
  29. ll inv(int i) {
  30. return binpow(i, MOD - 2);
  31. }
  32.  
  33. ll nCk(int n, int k) {
  34. // nC0 = 1
  35. ll ans = 1;
  36. // O(k)
  37. ll sum = 0;
  38. for (int i = 1; i <= k; i++) {
  39. ans = ans * (n - i + 1) % MOD * inv(i) % MOD;
  40. }
  41. return ans;
  42. }
  43.  
  44. int main() {
  45. ios::sync_with_stdio(0); cin.tie(0);
  46. int n, k;
  47. cin >> n >> k;
  48. cout << nCk(n, k) << '\n';
  49. }
Success #stdin #stdout 0.11s 5304KB
stdin
1000000000 1000000
stdout
336556208