結果
問題 | No.117 組み合わせの数 |
ユーザー | abUma |
提出日時 | 2023-04-23 01:42:07 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 667 ms / 5,000 ms |
コード長 | 2,630 bytes |
コンパイル時間 | 208 ms |
コンパイル使用メモリ | 82,688 KB |
実行使用メモリ | 243,968 KB |
最終ジャッジ日時 | 2024-11-07 12:02:43 |
合計ジャッジ時間 | 2,190 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
ソースコード
from typing import List class Binominal: def __init__(self, mod: int, max: int=0) -> None: self.mod = mod self.f = f = [1] self.g = [1] self.h = [1] while max >= len(f): self.extend() def extend(self) -> None: mod = self.mod f, g, h = self.f, self.g, self.h n = len(f) m = n << 1 f[n:] = [0] * n g[n:] = [0] * n h[n:] = [0] * n for i in range(n, m): f[i] = f[i - 1] * i % mod g[-1] = pow(f[-1], mod - 2, mod) h[-1] = g[-1] * f[-2] % mod for i in range(m - 2, n - 1, -1): g[i] = g[i + 1] * (i + 1) % mod h[i] = g[i] * f[i - 1] % mod def fac(self, i: int) -> int: if i < 0: return 0 f = self.f; extend = self.extend while i >= len(f): extend() return f[i] def finv(self, i: int) -> int: if i < 0: return 0 g = self.g; extend = self.extend while i >= len(g): extend() return g[i] def inv(self, i: int) -> int: if i < 0: tmp = pow(-i, self.mod - 2, self.mod) if tmp: return self.mod - tmp else: return 0 h = self.h; extend = self.extend while i > len(h): extend() return h[i] def __call__(self, n: int, r: int) -> int: return self.C(n, r) def multinominal(self, r: List[int]) -> int: n = 0 for x in r: if x < 0: return 0 n += x res = self.fac(n) mod = self.mod; finv = self.finv for x in r: res = res * finv(x) % mod return res def C_naive(self, n: int, r: int) -> int: if n < 0 or n < r or r < 0: return 0 mod = self.mod res = 1 r = min(r, n - r) for i in range(1, r + 1): res = (res * pow(i, mod - 2, mod) % mod) * n n -= 1 return res def C(self, n: int, r: int) -> int: if n < 0 or n < r or r < 0: return 0 return (self.fac(n) * self.finv(n - r) % self.mod) * self.finv(r) % self.mod def P(self, n: int, r: int) -> int: if n < 0 or n < r or r < 0: return 0 return self.fac(n) * self.finv(n - r) % self.mod def H(self, n: int, r: int) -> int: if n < 0 or r < 0: return 0 return self.C(n + r - 1, r) if r else 1 T = int(input()) binominal = Binominal(1_000_000_007) for _ in range(T): S = input() n, r = map(int,S[2:-1].split(',')) if S[0] == "C": print(binominal.C(n, r)) elif S[0] == "P": print(binominal.P(n, r)) else: print(binominal.H(n, r))