Problem p02862 (python)

Fixed submission:
# 入力が10**5とかになったときに100ms程度早い
import sys
read = sys.stdin.readline


def read_ints():
    return list(map(int, read().split()))


def read_a_int():
    return int(read())


def read_matrix(H):
    '''
    H is number of rows
    '''
    return [list(map(int, read().split())) for _ in range(H)]


def read_map(H):
    '''
    H is number of rows
    文字列で与えられた盤面を読み取る用
    '''
    return [read()[:-1] for _ in range(H)]


def read_col(H, n_cols):
    '''
    H is number of rows
    n_cols is number of cols

    A列、B列が与えられるようなとき
    '''
    ret = [[] for _ in range(n_cols)]
    for _ in range(H):
        tmp = list(map(int, read().split()))
        for col in range(n_cols):
            ret[col].append(tmp[col])

    return ret


MOD = 10**9 + 7

X, Y = read_ints()
if (X + Y) % 3 != 0:  # !=0
    print(0)
    exit()

pascal_depth = int((X + Y) / 3)  # パスカルの三角形に当たるn
x, y = int((X + Y) * 2 / 3), (X + Y) / 3
pascal_k = x - X  # 端からいくつずれているか

if pascal_k > pascal_depth / 2:
    pascal_k = pascal_depth - pascal_k

# ans = 1
# # for k in range(int(pascal_k), 0, -1):
# #     ans *= pascal_depth
# #     # print(ans)
# #     pascal_depth -= 1
# #     if ans > MOD:
# #         ans %= MOD

# # for k in range(int(pascal_k), 0, -1):
# # フェルマーの少定理jを使ってみる
# for i in range(1, int(pascal_depth) + 1):
#     ans *= i
#     if ans > MOD:
#         ans %= MOD

# from math import factorial
# # k_fact = factorial(pascal_k)
# k_fact = 1
# # k_fact
# for i in range(1, pascal_k + 1):
#     k_fact *= i
#     if k_fact > MOD:
#         k_fact %= MOD
# ans *= k_fact**(MOD - 2) % MOD
# # nk_fact = factorial(pascal_depth - pascal_k)
# nk_fact = 1
# for i in range(1, int(pascal_depth - pascal_k) + 1):
#     nk_fact *= i
#     if nk_fact > MOD:
#         nk_fact %= MOD

# ans *= nk_fact**(MOD - 2) % MOD


def cmb(n, r, mod):
    if (r < 0 or r > n):
        return 0
    r = min(r, n - r)
    return g1[n] * g2[r] * g2[n - r] % mod


mod = 10**9 + 7  # 出力の制限
N = pascal_depth
g1 = [1, 1]  # 元テーブル
g2 = [1, 1]  # 逆元テーブル
inverse = [0, 1]  # 逆元テーブル計算用テーブル

for i in range(2, N + 1):
    g1.append((g1[-1] * i) % mod)
    inverse.append((-inverse[mod % i] * (mod // i)) % mod)
    g2.append((g2[-1] * inverse[-1]) % mod)


a = cmb(pascal_depth, pascal_k, mod)
print(a)

Buggy submission (verdict: Runtime Error):
# 入力が10**5とかになったときに100ms程度早い
import sys
read = sys.stdin.readline


def read_ints():
    return list(map(int, read().split()))


def read_a_int():
    return int(read())


def read_matrix(H):
    '''
    H is number of rows
    '''
    return [list(map(int, read().split())) for _ in range(H)]


def read_map(H):
    '''
    H is number of rows
    文字列で与えられた盤面を読み取る用
    '''
    return [read()[:-1] for _ in range(H)]


def read_col(H, n_cols):
    '''
    H is number of rows
    n_cols is number of cols

    A列、B列が与えられるようなとき
    '''
    ret = [[] for _ in range(n_cols)]
    for _ in range(H):
        tmp = list(map(int, read().split()))
        for col in range(n_cols):
            ret[col].append(tmp[col])

    return ret


MOD = 10**9 + 7

X, Y = read_ints()
if (X + Y) % 3 != 0:  # !=0
    print(0)
    exit()

pascal_depth = int((X + Y) / 3)  # パスカルの三角形に当たるn
x, y = int((X + Y) * 2 / 3), (X + Y) / 3
pascal_k = x - X  # 端からいくつずれているか

if pascal_k > pascal_depth / 2:
    pascal_k = pascal_depth - pascal_k


# def cmb(n, r, mod):
#     if (r < 0 or r > n):
#         return 0
#     r = min(r, n - r)
#     return g1[n] * g2[r] * g2[n - r] % mod


# mod = 10**9 + 7  # 出力の制限
# N = pascal_depth
# g1 = [1, 1]  # 元テーブル
# g2 = [1, 1]  # 逆元テーブル
# inverse = [0, 1]  # 逆元テーブル計算用テーブル

# for i in range(2, N + 1):
#     g1.append((g1[-1] * i) % mod)
#     inverse.append((-inverse[mod % i] * (mod // i)) % mod)
#     g2.append((g2[-1] * inverse[-1]) % mod)

import sys
sys.setrecursionlimit(2**16)


def mod_combination(n, k, mod):
    # nCk (mod m)
    def mod_permutation(n, k, mod):
        if n <= k:
            return 1
        else:
            return (n * mod_permutation(n - 1, k, mod)) % mod

    def mod_inv_permutation(k, mod):
        k, mod = int(k), int(mod)
        if k <= 1:
            return 1
        else:
            return (pow(k, mod - 2, mod) * mod_inv_permutation(k - 1, mod)) % mod

    return (mod_permutation(n, n - k, mod) * mod_inv_permutation(k, mod)) % mod


a = mod_combination(pascal_depth, pascal_k, MOD)
print(a)

Buggy submission (verdict: Runtime Error):
# 入力が10**5とかになったときに100ms程度早い
import sys
read = sys.stdin.readline


def read_ints():
    return list(map(int, read().split()))


def read_a_int():
    return int(read())


def read_matrix(H):
    '''
    H is number of rows
    '''
    return [list(map(int, read().split())) for _ in range(H)]


def read_map(H):
    '''
    H is number of rows
    文字列で与えられた盤面を読み取る用
    '''
    return [read()[:-1] for _ in range(H)]


def read_col(H, n_cols):
    '''
    H is number of rows
    n_cols is number of cols

    A列、B列が与えられるようなとき
    '''
    ret = [[] for _ in range(n_cols)]
    for _ in range(H):
        tmp = list(map(int, read().split()))
        for col in range(n_cols):
            ret[col].append(tmp[col])

    return ret


MOD = 10**9 + 7

X, Y = read_ints()
if (X + Y) % 3 != 0:  # !=0
    print(0)
    exit()

pascal_depth = int((X + Y) / 3)  # パスカルの三角形に当たるn
x, y = int((X + Y) * 2 / 3), (X + Y) / 3
pascal_k = x - X  # 端からいくつずれているか

if pascal_k > pascal_depth / 2:
    pascal_k = pascal_depth - pascal_k


def cmb(n, r, mod):
    if (r < 0 or r > n):
        return 0
    r = min(r, n - r)
    return g1[n] * g2[r] * g2[n - r] % mod


mod = 10**9 + 7  # 出力の制限
N = pascal_depth
g1 = [1, 1]  # 元テーブル
g2 = [1, 1]  # 逆元テーブル
inverse = [0, 1]  # 逆元テーブル計算用テーブル

for i in range(2, N + 1):
    g1.append((g1[-1] * i) % mod)
    inverse.append((-inverse[mod % i] * (mod // i)) % mod)
    g2.append((g2[-1] * inverse[-1]) % mod)


def mod_combination(n, k, mod):
    # nCk (mod m)
    def mod_permutation(n, k, mod):
        if n <= k:
            return 1
        else:
            return (n * mod_permutation(n - 1, k, mod)) % mod

    def mod_inv_permutation(k, mod):
        k, mod = int(k), int(mod)
        if k <= 1:
            return 1
        else:
            return (pow(k, mod - 2, mod) * mod_inv_permutation(k - 1, mod)) % mod

    return (mod_permutation(n, n - k, mod) * mod_inv_permutation(k, mod)) % mod


a = mod_combination(pascal_depth, pascal_k, MOD)
print(a)