Problem p02862 (python)

Fixed submission:
# 階乗は英語でfactrial, ifacは階乗に対する逆元
def cmb(n, k, mod, fac, ifac):
    # nCkを求める
    k = min(k, n-k)
    return fac[n] * ifac[k] * ifac[n-k] % mod


def make_tables(mod, n):  # (mod mod)の世界における割り算に従ってテーブルを作る
    # 階乗, 階乗に対する逆元のテーブルを作成する
    fac = [1, 1]  # 階乗デーブル
    ifac = [1, 1]  # 階乗に対する逆元のテーブル
    inverse = [0, 1]  # 逆元そのもののテーブル

    for i in range(2, n+1):
        fac.append((fac[-1] * i) % mod)
        inverse.append((-inverse[mod % i] * (mod//i)) % mod)
        ifac.append((ifac[-1] * inverse[-1]) % mod)
    return fac, ifac


X, Y = map(int, input().split())
MOD = 1000000007
if (X+Y) % 3 != 0:
    print(0)
else:
    m = (2*X-Y)//3
    n = X - 2*m
    if n < 0 or m < 0:
        print(0)
        exit()
    fac, ifac = make_tables(MOD, (X+Y)//3)
    ans = cmb(n+m, n, MOD, fac, ifac)
    print(ans)

Buggy submission (verdict: Runtime Error):
import math
X, Y = map(int, input().split())  # 目的地

# dp = [[0]*(X+1) for _ in range(Y+1)]
#
# dp[2][1] = 1
# dp[1][2] = 1
#
# for i in range(Y+1):  # iがy座標にあたる
#     for j in range(X+1):  # jがx座標にあたる
#         if i < 2 or j < 2:
#             continue
#         dp[i][j] += dp[i-1][j-2] + dp[i-2][j-1]
#
# print(dp[Y][X])

# dp_x = [0]*(X+1)
# dp_x[1] = 1
# dp_x[2] = 2
# for i in range(3, X+1):  # Xの動きだけ専門
#     dp_x[i] += dp_x[i-1] + dp_x[i-2]
#
# dp_y = [0]*(Y+1)
# dp_y[1] = 1
# dp_y[2] = 2
# for i in range(3, Y+1):
#     dp_y[i] += dp_y[i-1] + dp_y[i-2]
# print(dp_x[X-1]*dp_y[Y-1]%1000000007)
# # print(dp_x)
# # print(dp_y)

#
# dp = [[0]*4 for _ in range(4)]
# for

if (X+Y)%3 != 0 or not(min(X, Y)*2 >= max(X, Y)):
    print(0)
    exit()
dp = [0]*(min(X, Y)+1)
dp[1] = 1
dp[2] = 2
for i in range(3, len(dp)):
    dp[i] += (dp[i-1] + dp[i-2])%1000000007

print(sum(dp[math.ceil(max(X, Y)/2):-1])%1000000007)
# print(dp)

Buggy submission (verdict: Runtime Error):
import math
X, Y = map(int, input().split())  # 目的地

# dp = [[0]*(X+1) for _ in range(Y+1)]
#
# dp[2][1] = 1
# dp[1][2] = 1
#
# for i in range(Y+1):  # iがy座標にあたる
#     for j in range(X+1):  # jがx座標にあたる
#         if i < 2 or j < 2:
#             continue
#         dp[i][j] += dp[i-1][j-2] + dp[i-2][j-1]
#
# print(dp[Y][X])

# dp_x = [0]*(X+1)
# dp_x[1] = 1
# dp_x[2] = 2
# for i in range(3, X+1):  # Xの動きだけ専門
#     dp_x[i] += dp_x[i-1] + dp_x[i-2]
#
# dp_y = [0]*(Y+1)
# dp_y[1] = 1
# dp_y[2] = 2
# for i in range(3, Y+1):
#     dp_y[i] += dp_y[i-1] + dp_y[i-2]
# print(dp_x[X-1]*dp_y[Y-1]%1000000007)
# # print(dp_x)
# # print(dp_y)

#
# dp = [[0]*4 for _ in range(4)]
# for

if (X+Y)%3 != 0:
    print(0)
    exit()
dp = [0]*(min(X, Y)+1)
dp[1] = 1
dp[2] = 2
for i in range(3, len(dp)):
    dp[i] += (dp[i-1] + dp[i-2])%1000000007

print(sum(dp[math.ceil(max(X, Y)/2):-1])%1000000007)
# print(dp)

Buggy submission (verdict: Runtime Error):
X, Y = map(int, input().split())  # 目的地
#
dp = [[0]*(X+1) for _ in range(Y+1)]

dp[2][1] = 1
dp[1][2] = 1

for i in range(Y+1):  # iがy座標にあたる
    for j in range(X+1):  # jがx座標にあたる
        if i < 2 or j < 2:
            continue
        dp[i][j] += dp[i-1][j-2] + dp[i-2][j-1]

print(dp[Y][X])

# dp_x = [0]*(X+1)
# dp_x[1] = 1
# dp_x[2] = 2
# for i in range(3, X+1):  # Xの動きだけ専門
#     dp_x[i] += dp_x[i-1] + dp_x[i-2]
#
# dp_y = [0]*(Y+1)
# dp_y[1] = 1
# dp_y[2] = 2
# for i in range(3, Y+1):
#     dp_y[i] += dp_y[i-1] + dp_y[i-2]
# print(dp_x[X-1]*dp_y[Y-1]%1000000007)
# # print(dp_x)
# # print(dp_y)