|
| 1 | +import sys |
| 2 | + |
| 3 | +read = lambda: sys.stdin.readline().rstrip() |
| 4 | + |
| 5 | + |
| 6 | +class Problem: |
| 7 | + def __init__(self): |
| 8 | + self.n = int(read()) |
| 9 | + self.data = [tuple(map(int, read().split())) for _ in range(self.n)] |
| 10 | + |
| 11 | + self.mod = 1_000_000_007 |
| 12 | + |
| 13 | + def solve(self) -> None: |
| 14 | + factorial, inverse_factorial = self.precompute_factorial() |
| 15 | + |
| 16 | + for n, r in self.data: |
| 17 | + print(self.comb(factorial, inverse_factorial, n, r)) |
| 18 | + |
| 19 | + def precompute_factorial(self) -> tuple[list[int], list[int]]: |
| 20 | + maximum = max(n for n, _ in self.data) |
| 21 | + factorial, inverse_factorial = [1] * (maximum + 1), [1] * (maximum + 1) |
| 22 | + |
| 23 | + for idx in range(1, maximum + 1): |
| 24 | + factorial[idx] = factorial[idx - 1] * idx % self.mod |
| 25 | + |
| 26 | + inverse_factorial[maximum] = pow(factorial[maximum], self.mod - 2, self.mod) |
| 27 | + for idx in range(maximum - 1, -1, -1): |
| 28 | + inverse_factorial[idx] = inverse_factorial[idx + 1] * (idx + 1) % self.mod |
| 29 | + |
| 30 | + return factorial, inverse_factorial |
| 31 | + |
| 32 | + def comb(self, factorial: list[int], inverse_factorial: list[int], n: int, r: int) -> int: |
| 33 | + if r < 0 or r > n: |
| 34 | + return 0 |
| 35 | + |
| 36 | + return factorial[n] * inverse_factorial[r] % self.mod * inverse_factorial[n - r] % self.mod |
| 37 | + |
| 38 | + |
| 39 | +if __name__ == "__main__": |
| 40 | + Problem().solve() |
0 commit comments