結果
問題 |
No.1044 正直者大学
|
ユーザー |
![]() |
提出日時 | 2025-05-14 13:25:18 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 124 ms / 2,000 ms |
コード長 | 3,684 bytes |
コンパイル時間 | 310 ms |
コンパイル使用メモリ | 82,400 KB |
実行使用メモリ | 65,172 KB |
最終ジャッジ日時 | 2025-05-14 13:26:15 |
合計ジャッジ時間 | 3,030 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 28 |
ソースコード
import sys def solve(): N, M, K = map(int, sys.stdin.readline().split()) MOD = 1_000_000_007 # Determine max needed for factorial calculations if M == 0: max_idx_needed = N # For fact[N-1], need up to N-1 if N>0, or N if N is used directly. # N-1 can be 0 if N=1. N can be up to 10^5. # To be safe, if N-1 is used, fact table needs up to N-1. # For fact[N-1], max index is N-1. Array size N. # Let's make it simple: max index used is max(N, M). else: max_idx_needed = max(N, M) # max_idx_needed could be 0 if N=0, M=0. But N>=1. So min max_idx_needed is 1 (for N=1,M=0 or N=1,M=1). # Array of size max_idx_needed + 1 for indices 0 to max_idx_needed. fact = [1] * (max_idx_needed + 1) invfact = [1] * (max_idx_needed + 1) for i in range(1, max_idx_needed + 1): fact[i] = (fact[i-1] * i) % MOD # invfact[0] is 1. If max_idx_needed is 0, this loop doesn't run for invfact[0]. # pow(0, MOD-2) is undefined. fact[0] is 1. if max_idx_needed >= 0 : # fact[0] always exists if fact[max_idx_needed] == 0 and max_idx_needed >= MOD : # Only if MOD is not prime and max_idx_needed >= MOD # This case should not happen with prime MOD or max_idx_needed < MOD # For MOD = 10^9+7, max_idx_needed = 10^5, fact[max_idx_needed] is non-zero. pass # Should handle if fact[max_idx_needed] could be 0 invfact[max_idx_needed] = pow(fact[max_idx_needed], MOD-2, MOD) for i in range(max_idx_needed - 1, -1, -1): invfact[i] = (invfact[i+1] * (i+1)) % MOD # else case (max_idx_needed < 0) is not possible due to N >= 1. def nCr_mod(n, r): if r < 0 or r > n: return 0 # n is N-1 or M-1. min N=1, so n can be 0. # fact[n], invfact[r], invfact[n-r] must be valid. num = fact[n] den = (invfact[r] * invfact[n-r]) % MOD return (num * den) % MOD ans = 0 if M == 0: # All N students are Honesty. N announcements of Honesty. if N >= K: # (N-1)! ways to arrange N distinct people in a circle. # fact[0] is 1, so fact[N-1] works for N=1. ans = fact[N-1] # else: ans = 0 (already initialized) else: # M > 0 (so M >= 1) # N >= 1 is given. # Number of announced H = N + M - 2b >= K # 2b <= N + M - K # b <= (N + M - K) / 2 b_limit_from_K = (N + M - K) // 2 # Max b for formula is min(N, M). # Also b must be <= b_limit_from_K. # b must be >= 1. upper_b_for_loop = min(N, M) if b_limit_from_K < 1: upper_b_for_loop = 0 # No valid b >= 1 if K is too large else: upper_b_for_loop = min(upper_b_for_loop, b_limit_from_K) current_sum = 0 for b in range(1, upper_b_for_loop + 1): term_comb_N = nCr_mod(N-1, b-1) term_comb_M = nCr_mod(M-1, b-1) # Optimization: if either combination is 0, the term is 0. if term_comb_N == 0 or term_comb_M == 0: continue numerator = (fact[N] * fact[M]) % MOD inv_b = pow(b, MOD-2, MOD) # b is always >= 1 here. term = numerator term = (term * inv_b) % MOD term = (term * term_comb_N) % MOD term = (term * term_comb_M) % MOD current_sum = (current_sum + term) % MOD ans = current_sum print(ans) solve()