Problem p03025 (python)

Fixed submission:
# WARN: Require mod number m is prime number
class ModComb:
    # For nCr mod m
    def __init__(self, n_max, m):
        self._n_max = n_max
        self._m = m
        self._mod_facts = [1] * (n_max+1)       # list of n! mod m
        self._mod_inv_facts = [1] * (n_max+1)   # list of inverse r! mod m

        if not m >= 3:
            raise ValueError('Require mod number m >= 3')

        # Calc n_max! mod m
        for i in range(2, n_max+1):
            self._mod_facts[i] = self._mod_facts[i-1] * i % m

        # Calc inverse r! mod m
        self._mod_inv_facts[n_max] = pow(self._mod_facts[n_max], m-2, m)
        for i in range(n_max-1, 1, -1):
            self._mod_inv_facts[i] = self._mod_inv_facts[i+1] * (i+1) % m

    def calc(self, n, r):
        # Return nCr mod m
        if n > self._n_max:
            raise Exception('n is larger than n_max')

        if r == 0:
            return 1

        m = self._m
        return self._mod_facts[n] * self._mod_inv_facts[r] * self._mod_inv_facts[n-r] % m


# n^p % mod
def modPower(mod, n, p):
    ret = 1
    for i in range(p):
        ret = ret*n % mod
    return ret


# Expected value of the number of all games when M-th non-even game occurs
def expectedGameNum(mod, C, M):
    return M*100*pow(100-C, mod-2, mod) % mod


# Probability of ending game when M-th non-even game occurs
def probEndGame(mod, modcomb, A, B, M, N):
    winA = modcomb.calc(M-1, N-1) * \
            (modPower(mod, A, N) * pow(modPower(mod, 100, N), mod-2, mod) % mod) * \
            (modPower(mod, B, M-N) * pow(modPower(mod, 100, M-N), mod-2, mod) % mod) % mod
    winB = modcomb.calc(M-1, N-1) * \
            (modPower(mod, B, N) * pow(modPower(mod, 100, N), mod-2, mod) % mod) * \
            (modPower(mod, A, M-N) * pow(modPower(mod, 100, M-N), mod-2, mod) % mod) % mod
    return (winA + winB) % mod

def main():
    MOD = 10**9+7
    N, A, B, C = map(int, input().split())
    N_MAX = 100000
    modcomb = ModComb(N_MAX*2, MOD)
    denomi100minusC = pow(100-C, MOD-2, MOD)
    modpowerA = [1] * (N+1)
    for i in range(1, N+1):
        modpowerA[i] = modpowerA[i-1] * A % MOD
    modpowerB = [1] * (N+1)
    for i in range(1, N+1):
        modpowerB[i] = modpowerB[i-1] * B % MOD
    modpower100 = [1] * (N+1)
    for i in range(1, N+1):
        modpower100[i] = modpower100[i-1] * 100 % MOD
    modpowerAB = [1] * (N+1)
    for i in range(1, N+1):
        modpowerAB[i] = modpowerAB[i-1] * (A+B) % MOD
    ans = 0
    for i in range(N, 2*N):
        prob_winA = modcomb.calc(i-1, N-1) * \
                (modpowerA[N] * pow(modpowerAB[N], MOD-2, MOD) % MOD) * \
                (modpowerB[i-N] * pow(modpowerAB[i-N], MOD-2, MOD) % MOD) % MOD
        prob_winB = modcomb.calc(i-1, N-1) * \
                (modpowerB[N] * pow(modpowerAB[N], MOD-2, MOD) % MOD) * \
                (modpowerA[i-N] * pow(modpowerAB[i-N], MOD-2, MOD) % MOD) % MOD
        prob_end_game = (prob_winA + prob_winB) % MOD
        ans += i*100*denomi100minusC % MOD * prob_end_game
        ans %= MOD
    print(ans)


if __name__ == '__main__':
    main()

Buggy submission (verdict: Runtime Error):
# WARN: Require mod number m is prime number
class ModComb:
    # For nCr mod m
    def __init__(self, n_max, m):
        self._n_max = n_max
        self._m = m
        self._mod_facts = [1] * (n_max+1)       # list of n! mod m
        self._mod_inv_facts = [1] * (n_max+1)   # list of inverse r! mod m

        if not m >= 3:
            raise ValueError('Require mod number m >= 3')

        # Calc n_max! mod m
        for i in range(2, n_max+1):
            self._mod_facts[i] = self._mod_facts[i-1] * i % m

        # Calc inverse r! mod m
        self._mod_inv_facts[n_max] = pow(self._mod_facts[n_max], m-2, m)
        for i in range(n_max-1, 1, -1):
            self._mod_inv_facts[i] = self._mod_inv_facts[i+1] * (i+1) % m

    def calc(self, n, r):
        # Return nCr mod m
        if n > self._n_max:
            raise Exception('n is larger than n_max')

        if r == 0:
            return 1

        m = self._m
        return self._mod_facts[n] * self._mod_inv_facts[r] * self._mod_inv_facts[n-r] % m


# n^p % mod
def modPower(mod, n, p):
    ret = 1
    for i in range(p):
        ret = ret*n % mod
    return ret


# Expected value of the number of all games when M-th non-even game occurs
def expectedGameNum(mod, C, M):
    return M*100*pow(100-C, mod-2, mod) % mod


# Probability of ending game when M-th non-even game occurs
def probEndGame(mod, modcomb, A, B, M, N):
    winA = modcomb.calc(M-1, N-1) * \
            (modPower(mod, A, N) * pow(modPower(mod, 100, N), mod-2, mod) % mod) * \
            (modPower(mod, B, M-N) * pow(modPower(mod, 100, M-N), mod-2, mod) % mod) % mod
    winB = modcomb.calc(M-1, N-1) * \
            (modPower(mod, B, N) * pow(modPower(mod, 100, N), mod-2, mod) % mod) * \
            (modPower(mod, A, M-N) * pow(modPower(mod, 100, M-N), mod-2, mod) % mod) % mod
    return (winA + winB) % mod

  def main():
    MOD = 10**9+7
    N, A, B, C = map(int, input().split())
    N_MAX = 100000
    modcomb = ModComb(N_MAX*2, MOD)
    ans = 0
    for i in range(N, 2*N):
        ans += expectedGameNum(MOD, C, i) * probEndGame(MOD, modcomb, A, B, i, N) % MOD
        ans %= MOD
    print(ans)


if __name__ == '__main__':
    main()