結果
問題 | No.117 組み合わせの数 |
ユーザー | norioc |
提出日時 | 2020-05-22 14:18:44 |
言語 | D (dmd 2.106.1) |
結果 |
AC
|
実行時間 | 290 ms / 5,000 ms |
コード長 | 1,778 bytes |
コンパイル時間 | 7,589 ms |
コンパイル使用メモリ | 363,428 KB |
実行使用メモリ | 54,188 KB |
最終ジャッジ日時 | 2024-06-22 07:05:48 |
合計ジャッジ時間 | 8,920 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
ソースコード
import std; const MOD = 10^^9 + 7; long calc(string c, int n, int k, ModBinom binom) { if (c == "C") { if (n < k) return 0; return binom(n, k); } if (c == "P") { if (n < k) return 0; return binom.p(n, k); } if (c == "H") { if (n + k - 1 < 0) return 1; return binom(n + k - 1, k); } assert(false); } void main() { int t; scan(t); auto reg = regex(r"(C|P|H)\((\d+),(\d+)\)"); auto binom = new ModBinom(3 * 10^^6); foreach (_; 0..t) { auto m = read.matchFirst(reg); string c = m[1]; int n = m[2].to!int; int k = m[3].to!int; writeln(calc(c, n, k, binom)); } } void scan(T...)(ref T a) { string[] ss = readln.split; foreach (i, t; T) a[i] = ss[i].to!t; } T read(T=string)() { return readln.chomp.to!T; } T[] reads(T)() { return readln.split.to!(T[]); } alias readints = reads!int; long modpow(long x, long k) { if (k == 0) return 1; if (k % 2 == 0) return modpow(x * x % MOD, k / 2); return x * modpow(x, k - 1) % MOD; } class ModBinom { private long[] _fact; private long[] _invfact; this(size_t size) { _fact = new long[size + 10]; _invfact = new long[size + 10]; init(); } private void init() { auto n = _fact.length; _fact[0] = 1; foreach (i; 1..n) _fact[i] = _fact[i-1] * i % MOD; _invfact[n-1] = modpow(_fact[n-1], MOD-2); foreach_reverse (i; 0..n-1) _invfact[i] = _invfact[i+1] * (i+1) % MOD; } long opCall(int n, int k) const { return (_fact[n] * _invfact[k] % MOD) * _invfact[n-k] % MOD; } long p(int n, int k) const { return _fact[n] * _invfact[n-k] % MOD; } }