結果
| 問題 |
No.1044 正直者大学
|
| コンテスト | |
| ユーザー |
qwewe
|
| 提出日時 | 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()
qwewe