Problem:


Score : 400 points

Problem Statement

There is a knight - the chess piece - at the origin (0, 0) of a two-dimensional grid.

When the knight is at the square (i, j), it can be moved to either (i+1,j+2) or (i+2, j+1).

In how many ways can the knight reach the square (X, Y)?

Find the number of ways modulo 10^9 + 7.

Constraints

1 \leq X \leq 10^6

1 \leq Y \leq 10^6

All values in input are integers.

Input

Input is given from Standard Input in the following format:

X Y

Output

Print the number of ways for the knight to reach (X, Y) from (0, 0), modulo 10^9 + 7.

Sample Input 1

3 3

Sample Output 1

2

There are two ways: (0,0) \to (1,2) \to (3,3) and (0,0) \to (2,1) \to (3,3).

Sample Input 2

2 2

Sample Output 2

0

The knight cannot reach (2,2).

Sample Input 3

999999 999999

Sample Output 3

151840682

Print the number of ways modulo 10^9 + 7.



Sample input:
3 3


Sample output:
2

Submission status: Accepted

Solution code:
class Factorial():
    def __init__(self, mod=10**9 + 7):
        self.mod = mod
        self._factorial = [1]
        self._size = 1
        self._factorial_inv = [1]
        self._size_inv = 1

    def __call__(self, n):
        return self.fact(n)

    def fact(self, n):
        ''' n! % mod '''
        if n >= self.mod:
            return 0
        self._make(n)
        return self._factorial[n]
    
    def _make(self, n):
        if n >= self.mod:
            n = self.mod
        if self._size < n+1:
            for i in range(self._size, n+1):
                self._factorial.append(self._factorial[i-1]*i % self.mod)
            self._size = n+1

    def fact_inv(self, n):
        ''' n!^-1 % mod '''
        if n >= self.mod:
            raise ValueError('Modinv is not exist! arg={}'.format(n))
        self._make(n)
        if self._size_inv < n+1:
            self._factorial_inv += [-1] * (n+1-self._size_inv)
            self._size_inv = n+1
        if self._factorial_inv[n] == -1:
            self._factorial_inv[n] = self.modinv(self._factorial[n])
        return self._factorial_inv[n]
    
    @staticmethod
    def xgcd(a, b):
        '''
        Return (gcd(a, b), x, y) such that a*x + b*y = gcd(a, b)
        '''
        x0, x1, y0, y1 = 0, 1, 1, 0
        while a != 0:
            (q, a), b = divmod(b, a), a
            y0, y1 = y1, y0 - q * y1
            x0, x1 = x1, x0 - q * x1
        return b, x0, y0

    def modinv(self, n):
        g, x, _ = self.xgcd(n, self.mod)
        if g != 1:
            raise ValueError('Modinv is not exist! arg={}'.format(n))
        return x % self.mod

    def comb(self, n, r):
        ''' nCr % mod '''
        if r > n:
            return 0
        t = self(n)*self.fact_inv(n-r) % self.mod
        return t*self.fact_inv(r) % self.mod

    def comb_with_repetition(self, n, r):
        ''' nHr % mod '''
        t = self(n+r-1)*self.fact_inv(n-1) % self.mod
        return t*self.fact_inv(r) % self.mod

    def perm(self, n, r):
        ''' nPr % mod '''
        if r > n:
            return 0
        return self(n)*self.fact_inv(n-r) % self.mod

x, y = sorted(map(int, input().split()))
q, r = divmod(x+y, 3)
if r != 0:
    print(0)
else:
    comb = Factorial().comb
    print(comb(q, y-q))

Submission status: Accepted

Solution code:
class Factorial():
    def __init__(self, mod=10**9 + 7):
        self.mod = mod
        self._factorial = [1]
        self._size = 1
        self._factorial_inv = [1]
        self._size_inv = 1

    def __call__(self, n):
        return self.fact(n)

    def fact(self, n):
        ''' n! % mod '''
        if n >= self.mod:
            return 0
        self._make(n)
        return self._factorial[n]

    def fact_inv(self, n):
        ''' n!^-1 % mod '''
        if n >= self.mod:
            raise ValueError('Modinv is not exist! arg={}'.format(n))
        self._make(n)
        if self._size_inv < n+1:
            self._factorial_inv += [-1] * (n+1-self._size_inv)
            self._size_inv = n+1
        if self._factorial_inv[n] == -1:
            self._factorial_inv[n] = self.modinv(self._factorial[n])
        return self._factorial_inv[n]

    def comb(self, n, r):
        ''' nCr % mod '''
        if r > n:
            return 0
        t = self.fact_inv(n-r)*self.fact_inv(r) % self.mod
        return self(n)*t % self.mod

    def comb_with_repetition(self, n, r):
        ''' nHr % mod '''
        t = self.fact_inv(n-1)*self.fact_inv(r) % self.mod
        return self(n+r-1)*t % self.mod

    def perm(self, n, r):
        ''' nPr % mod '''
        if r > n:
            return 0
        return self(n)*self.fact_inv(n-r) % self.mod

    @staticmethod
    def xgcd(a, b):
        '''
        Return (gcd(a, b), x, y) such that a*x + b*y = gcd(a, b)
        '''
        x0, x1, y0, y1 = 0, 1, 1, 0
        while a != 0:
            (q, a), b = divmod(b, a), a
            y0, y1 = y1, y0 - q * y1
            x0, x1 = x1, x0 - q * x1
        return b, x0, y0

    def modinv(self, n):
        g, x, _ = self.xgcd(n, self.mod)
        if g != 1:
            raise ValueError('Modinv is not exist! arg={}'.format(n))
        return x % self.mod

    def _make(self, n):
        if n >= self.mod:
            n = self.mod
        if self._size < n+1:
            for i in range(self._size, n+1):
                self._factorial.append(self._factorial[i-1]*i % self.mod)
            self._size = n+1

    def _make_inv(self, n):
        if n >= self.mod:
            n = self.mod
        self._make(n)
        if self._size_inv < n+1:
            for i in range(self._size_inv, n+1):
                self._factorial_inv.append(self.modinv(self._factorial[i]))
            self._size_inv = n+1


x, y = sorted(map(int, input().split()))
q, r = divmod(x+y, 3)
if r != 0:
    print(0)
else:
    comb = Factorial().comb
    print(comb(q, y-q))

Submission status: Accepted

Solution code:
mod = 10**9 + 7
_factorial = [1]
def fact(n):
    ''' n! % mod '''
    if n >= mod:
        return 0
    _size = len(_factorial)
    if _size < n+1:
        for i in range(_size, n+1):
            _factorial.append(_factorial[i-1]*i % mod)
    return _factorial[n]
    
_factorial_inv = [1]
def fact_inv(n):
    ''' n!^-1 % mod '''
    if n >= mod:
        raise ValueError('Modinv is not exist! arg={}'.format(n))
    _size = len(_factorial)
    if _size < n+1:
        for i in range(_size, n+1):
            _factorial.append(_factorial[i-1]*i % mod)
    _size_inv = len(_factorial_inv)
    if _size_inv < n+1:
        for i in range(_size_inv, n+1):
            _factorial_inv.append(modinv(_factorial[i]))
    return _factorial_inv[n]
    
def comb(n, r):
    ''' nCr % mod '''
    if r > n:
        return 0
    t = fact(n) * modinv(fact(n-r)) % mod
    t = t * modinv(fact(r)) % mod
    return t

def xgcd(a, b):
    x0, x1, y0, y1 = 0, 1, 1, 0
    while a != 0:
        (q, a), b = divmod(b, a), a
        y0, y1 = y1, y0 - q * y1
        x0, x1 = x1, x0 - q * x1
    return b, x0, y0

def modinv(n):
    g, x, _ = xgcd(n, mod)
    if g != 1:
        raise ValueError('Modinv is not exist! arg={}'.format(n))
    return x % mod        

x, y = sorted(map(int, input().split()))
q, r = divmod(x+y, 3)
if r != 0:
    print(0)
else:
    print(comb(q, y-q))

Submission status: Accepted

Solution code:
mod = 10**9 + 7
_factorial = [1]
def fact(n):
    ''' n! % mod '''
    if n >= mod:
        return 0
    _size = len(_factorial)
    if _size < n+1:
        for i in range(_size, n+1):
            _factorial.append(_factorial[i-1]*i % mod)
    return _factorial[n]
    
_factorial_inv = [1]
def fact_inv(n):
    ''' n!^-1 % mod '''
    if n >= mod:
        raise ValueError('Modinv is not exist! arg={}'.format(n))
    _size = len(_factorial)
    if _size < n+1:
        for i in range(_size, n+1):
            _factorial.append(_factorial[i-1]*i % mod)
    _size_inv = len(_factorial_inv)
    if _size_inv < n+1:
        for i in range(_size_inv, n+1):
            _factorial_inv.append(modinv(_factorial[i]))
    return _factorial_inv[n]
    
def comb(n, r):
    ''' nCr % mod '''
    if r > n:
        return 0
    t = fact(n) * fact_inv(n-r) % mod
    t = t * fact_inv(r) % mod
    return t

def xgcd(a, b):
    x0, x1, y0, y1 = 0, 1, 1, 0
    while a != 0:
        (q, a), b = divmod(b, a), a
        y0, y1 = y1, y0 - q * y1
        x0, x1 = x1, x0 - q * x1
    return b, x0, y0

def modinv(n):
    g, x, _ = xgcd(n, mod)
    if g != 1:
        raise ValueError('Modinv is not exist! arg={}'.format(n))
    return x % mod        

x, y = sorted(map(int, input().split()))
q, r = divmod(x+y, 3)
if r != 0:
    print(0)
else:
    print(comb(q, y-q))

Submission status: Accepted

Solution code:
class Factorial():
    def __init__(self, mod=10**9 + 7):
        self.mod = mod
        self._factorial = [1]
        self._size = 1
        self._factorial_inv = [1]
        self._size_inv = 1

    def fact(self, n):
        ''' n! % mod '''
        if n >= self.mod:
            return 0
        if self._size < n+1:
            for i in range(self._size, n+1):
                self._factorial.append(self._factorial[i-1]*i % self.mod)
            self._size = n+1
        return self._factorial[n]

    def fact_inv(self, n):
        ''' n!^-1 % mod '''
        if n >= self.mod:
            raise ValueError('Modinv is not exist! arg={}'.format(n))
        if self._size < n+1:
            for i in range(self._size, n+1):
                self._factorial.append(self._factorial[i-1]*i % self.mod)
            self._size = n+1
        if self._size_inv < n+1:
            for i in range(self._size_inv, n+1):
                self._factorial_inv.append(self.modinv(self._factorial[i]))
            self._size_inv = n+1
        return self._factorial_inv[n]
    
    def comb(self, n, r):
        ''' nCr % mod '''
        if r > n:
            return 0
        t = self.fact(n) * self.fact_inv(n-r) % self.mod
        t = t * self.fact_inv(r) % self.mod
        return t

    @staticmethod
    def xgcd(a, b):
        '''
        Return (gcd(a, b), x, y) such that a*x + b*y = gcd(a, b)
        '''
        x0, x1, y0, y1 = 0, 1, 1, 0
        while a != 0:
            (q, a), b = divmod(b, a), a
            y0, y1 = y1, y0 - q * y1
            x0, x1 = x1, x0 - q * x1
        return b, x0, y0

    def modinv(self, n):
        g, x, _ = self.xgcd(n, self.mod)
        if g != 1:
            raise ValueError('Modinv is not exist! arg={}'.format(n))
        return x % self.mod        

x, y = sorted(map(int, input().split()))
q, r = divmod(x+y, 3)
if r != 0:
    print(0)
else:
    fact = Factorial()
    print(fact.comb(q, y-q))

Submission status: Accepted

Solution code:
class Factorial():
    def __init__(self, mod=10**9 + 7):
        self.mod = mod
        self._factorial = [1]
        self._size = 1
        self._factorial_inv = [1]
        self._size_inv = 1

    def __call__(self, n):
        return self.fact(n)

    def fact(self, n):
        ''' n! % mod '''
        if n >= self.mod:
            return 0
        self._make(n)
        return self._factorial[n]

    def fact_inv(self, n):
        ''' n!^-1 % mod '''
        if n >= self.mod:
            raise ValueError('Modinv is not exist! arg={}'.format(n))
        self._make_inv(n)
        return self._factorial_inv[n]

    def comb(self, n, r):
        ''' nCr % mod '''
        if r > n:
            return 0
        t = self.fact_inv(n-r)*self.fact_inv(r) % self.mod
        return self(n)*t % self.mod

    def comb_with_repetition(self, n, r):
        ''' nHr % mod '''
        t = self.fact_inv(n-1)*self.fact_inv(r) % self.mod
        return self(n+r-1)*t % self.mod

    def perm(self, n, r):
        ''' nPr % mod '''
        if r > n:
            return 0
        return self(n)*self.fact_inv(n-r) % self.mod

    @staticmethod
    def xgcd(a, b):
        '''
        Return (gcd(a, b), x, y) such that a*x + b*y = gcd(a, b)
        '''
        x0, x1, y0, y1 = 0, 1, 1, 0
        while a != 0:
            (q, a), b = divmod(b, a), a
            y0, y1 = y1, y0 - q * y1
            x0, x1 = x1, x0 - q * x1
        return b, x0, y0

    def modinv(self, n):
        g, x, _ = self.xgcd(n, self.mod)
        if g != 1:
            raise ValueError('Modinv is not exist! arg={}'.format(n))
        return x % self.mod

    def _make(self, n):
        if n >= self.mod:
            n = self.mod
        if self._size < n+1:
            for i in range(self._size, n+1):
                self._factorial.append(self._factorial[i-1]*i % self.mod)
            self._size = n+1

    def _make_inv(self, n):
        if n >= self.mod:
            n = self.mod
        self._make(n)
        if self._size_inv < n+1:
            for i in range(self._size_inv, n+1):
                self._factorial_inv.append(self.modinv(self._factorial[i]))
            self._size_inv = n+1

x, y = sorted(map(int, input().split()))
q, r = divmod(x+y, 3)
if r != 0:
    print(0)
else:
    fact = Factorial()
    fact._make(q)
    fact._make(y-q)
    print(fact.comb(q, y-q))

Submission status: Accepted

Solution code:
MOD = 10**9 + 7
def xgcd(a, b):
    x0, y0, x1, y1 = 1, 0, 0, 1
    while b != 0:
        q, a, b = a // b, b, a % b
        x0, x1 = x1, x0 - q * x1
        y0, y1 = y1, y0 - q * y1
    return a, x0, y0

def modinv(a, mod):
    g, x, y = xgcd(a, mod)
    assert g == 1, 'modular inverse does not exist'
    return x % mod

factorials = [1]
def factorial(n, mod):
    # n! % mod
    assert n >= 0, 'Argument Error! n is "0 <= n".'
    if len(factorials) < n+1:
        for i in range(len(factorials), n+1):
            factorials.append(factorials[-1]*i % mod)
    return factorials[n]

def comb(n, r, mod):
    # nCr % mod
    assert n >= 0, 'Argument Error! n is "0 <= n".'
    assert n >= r >= 0, 'Argument Error! r is "0 <= r <= n".'
    
    return perm(n, r, mod) * modinv(factorial(r, mod), mod) % mod

def perm(n, r, mod):
    # nPr % mod
    assert n >= 0, 'Argument Error! n is "0 <= n".'
    assert n >= r >= 0, 'Argument Error! r is "0 <= r <= n".'
    return factorial(n, mod) * modinv(factorial(n-r, mod), mod) % mod

x, y = sorted(map(int, input().split()))
MOD = 10 ** 9 + 7
q, r = divmod(x+y, 3)
 
if r != 0:
    print(0)
else:
    try:
        print(comb(q, y - q, MOD))
    except AssertionError:
        print(0)

Submission status: Accepted

Solution code:
class Factorial():
    def __init__(self, mod=10**9 + 7):
        self.mod = mod
        self._factorial = [1]
        self._size = 1
        self._factorial_inv = [1]
        self._size_inv = 1

    def __call__(self, n):
        return self.fact(n)

    def fact(self, n):
        ''' n! % mod '''
        if n >= self.mod:
            return 0
        self._make(n)
        return self._factorial[n]

    def fact_inv(self, n):
        ''' n!^-1 % mod '''
        if n >= self.mod:
            raise ValueError('Modinv is not exist! arg={}'.format(n))
        self._make_inv(n)
        return self._factorial_inv[n]

    def comb(self, n, r):
        ''' nCr % mod '''
        if r > n:
            return 0
        t = self.fact_inv(n-r)*self.fact_inv(r) % self.mod
        return self(n)*t % self.mod

    def comb_with_repetition(self, n, r):
        ''' nHr % mod '''
        t = self.fact_inv(n-1)*self.fact_inv(r) % self.mod
        return self(n+r-1)*t % self.mod

    def perm(self, n, r):
        ''' nPr % mod '''
        if r > n:
            return 0
        return self(n)*self.fact_inv(n-r) % self.mod

    @staticmethod
    def xgcd(a, b):
        '''
        Return (gcd(a, b), x, y) such that a*x + b*y = gcd(a, b)
        '''
        x0, x1, y0, y1 = 0, 1, 1, 0
        while a != 0:
            (q, a), b = divmod(b, a), a
            y0, y1 = y1, y0 - q * y1
            x0, x1 = x1, x0 - q * x1
        return b, x0, y0

    def modinv(self, n):
        g, x, _ = self.xgcd(n, self.mod)
        if g != 1:
            raise ValueError('Modinv is not exist! arg={}'.format(n))
        return x % self.mod

    def _make(self, n):
        if n >= self.mod:
            n = self.mod
        if self._size < n+1:
            for i in range(self._size, n+1):
                self._factorial.append(self._factorial[i-1]*i % self.mod)
            self._size = n+1

    def _make_inv(self, n):
        if n >= self.mod:
            n = self.mod
        self._make(n)
        if self._size_inv < n+1:
            for i in range(self._size_inv, n+1):
                self._factorial_inv.append(self.modinv(self._factorial[i]))
            self._size_inv = n+1

x, y = sorted(map(int, input().split()))
comb = Factorial().comb
q, r = divmod(x+y, 3)
if r != 0:
    print(0)
else:
    print(comb(q, y-q))

Submission status: Accepted

Solution code:
def build_combinations_counter(N=10**6, p=10**9+7):
    fact = [1, 1]  # fact[n] = (n! mod p)
    factinv = [1, 1]  # factinv[n] = ((n!)^(-1) mod p)
    inv = [0, 1]  # mod p におけるnの逆元 n^(-1)
    for i in range(2, N + 1):
        fact.append((fact[-1] * i) % p)
        inv.append((-inv[p % i] * (p // i)) % p)
        factinv.append((factinv[-1] * inv[-1]) % p)
    
    def cmb(n, r, p, fact, factinv):
        if (r < 0) or (n < r):
            return 0
        r = min(r, n - r)
        return fact[n] * factinv[r] * factinv[n-r] % p
    
    import functools
    return functools.partial(cmb, p=p, fact=fact, factinv=factinv)

def resolve():
    X, Y = list(map(int, input().split()))
    MOD = 10**9+7
    counter = build_combinations_counter(N=10**6, p=MOD)
    total = 0
    for x in range(X+1):
        if (X-x)/2 != Y-2*x:
            continue
        y = Y-2*x
        total += counter(x+y, x)
        total %= MOD
    print(total)


if '__main__' == __name__:
    resolve()

Submission status: Accepted

Solution code:
#abc145_d
m = 10**9+7
x,y = map(int,input().split())
fac =[0]*(10**6+1)
a = max(x,y)
b = min(x,y)
cnt = 0
fac[0]=1

while a != b:
    a -= 2
    b -= 1
    cnt +=1
    fac[cnt] = (fac[cnt-1]*cnt)%m

    if a<0 or b <0:
        print(0)
        exit()
c = a//3
d = cnt
if a%3 != 0:
    print(0)
    exit()
    
else:
    while a != 0:
        a -= 1
        b -= 2
        cnt +=1
        fac[cnt] = (fac[cnt-1]*cnt)%m

        a -= 2
        b -= 1
        cnt +=1
        fac[cnt] = (fac[cnt-1]*cnt)%m

n = ((fac[cnt])%m)*(pow(fac[c+d],m-2,m))*(pow(fac[c],m-2,m))
print(n%m)

Submission status: Accepted

Solution code:
import sys
def input(): return sys.stdin.readline().rstrip()


def main():
    mod = 10**9+7
    x, y = map(int, input().split())
    x2 = max(x, y)
    y2 = min(x, y)
    m = y2-(x2-y2)
    if m < 0 or m % 3 != 0:
        print(0)
    else:
        c = m // 3
        n = c*2+(x2-y2)
        bunshi = 1
        bunbo = 1
        for i in range(1, c+1):
            bunbo= bunbo*i % mod
            bunshi= bunshi*(n-i+1) % mod
    
        ans = bunshi * pow(bunbo,-1,mod)
        print(ans%mod)


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
x, y  = map(int, input().split())
mod = 10 ** 9 + 7
if (x + y) % 3 != 0:
    ans = 0
else:
    n, m = (2 * x - y) / 3, (2 * y - x) / 3
    ans = 0
    if n >= 0 and m >= 0:
        n, m = int(n), int(m)
        ans = 1
        for i in range(min(m, n)):
            ans = ans * (n + m - i) % mod 
            ans *= pow(i + 1, mod - 2, mod)

print(ans % mod)

Submission status: Accepted

Solution code:
x,y=map(int,input().split())
a=(2*x)-y
b=(2*y)-x
if a%3==0 and b%3==0 and a>=0 and b>=0:
    a=a//3
    b=b//3
    c=a+b
    a1=1
    a2=1
    n3=10**9+7
    for i in range(a):
        a1*=c-i
        a2*=i+1
        a1%=n3
        a2%=n3
    a2=pow(a2,n3-2,n3)
    print((a1*a2)%n3)
else:
    print(0)

Submission status: Accepted

Solution code:
MAX = 1000000
MOD = 1000000007

fac = [None] * MAX
finv = [None] * MAX
inv = [None] * MAX

def comb_init():
    fac[0] = fac[1] = 1
    finv[0] = finv[1] = 1
    inv[1] = 1
    for i in range(2, MAX):
        fac[i] = fac[i - 1] * i % MOD
        inv[i] = MOD - inv[MOD % i] * (MOD // i) % MOD
        finv[i] = finv[i - 1] * inv[i] % MOD

def comb(n, k):
    if n < 0 or k < 0 or n < k:
        return 0
    return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD

comb_init()
X, Y = map(int, input().split())

n = (2 * Y - X) // 3
m = (2 * X - Y) // 3

if (X + Y) % 3 != 0 or n < 0 or m < 0:
    print(0)
    exit()

print(comb(n + m, n))

Submission status: Accepted

Solution code:
def fact(n,mod):
    sm=1
    for i in range(2,n+1):
        sm*=i
        sm%=mod
    return sm

def main():
    mod=10**9+7
    x,y=map(int,input().split())
    if (x+y)%3!=0 : print(0);exit()
    times=(x+y)//3

    xwork,ywork=(x-times,y-times)

    if xwork<0 or ywork<0 : print(0);exit()

    sm=fact(times,mod)
    sm*=pow(fact(xwork,mod),mod-2,mod=mod)
    sm%=mod
    sm*=pow(fact(ywork,mod),mod-2,mod=mod)
    sm%=mod

    print(sm)

main()

Submission status: Accepted

Solution code:
def nCr(n, r, mod):
    x, y = 1, 1
    for i in range(1, r+1):
        x = x*(n+1-i)%mod
        y = y*i%mod
    return x*pow(y, mod-2, mod)%mod
a,b = map(int,input().split())
s=2*a-b
t=2*b-a
if s%3!=0 or s<0 or t%3!=0 or t<0:
  print(0)
else:
  print(nCr((s+t)//3,(t//3),10**9+7))

Submission status: Accepted

Solution code:
mod=10**9+7
x,y=map(int,input().split())
if (x+y)%3!=0:
    print(0)
    exit()
a=min(x,y)
b=max(x,y)
if 2*a<b:
    print(0)
    exit()

k=(x+y)//3
left_x=2*k
left_y=k
r=left_x-x

def factorialmod(n,mod):
    ans=1
    for i in range(2,n+1):
        ans*=i
        ans%=mod
    return ans

fac_k=factorialmod(k,mod)
fac_k_r=factorialmod(k-r,mod)
fac_r=factorialmod(r,mod)
bunbo=fac_k_r*fac_r%mod
print(fac_k*pow(bunbo,mod-2,mod)%mod)

Submission status: Accepted

Solution code:
import sys
input = lambda : sys.stdin.readline().rstrip()
sys.setrecursionlimit(max(1000, 10**9))
write = lambda x: sys.stdout.write(x+"\n")


x,y = list(map(int, input().split()))

### 素数の逆元とCombination
M = 10**9+7 # 出力の制限
N = (x+y)//3 * 2 +100 # 必要なテーブルサイズ

g1 = [None] * (N+1) # 元テーブル
g2 = [None] * (N+1) #逆元テーブル
inverse = [None] * (N+1) #逆元テーブル計算用テーブル
g1[0] = g1[1] = g2[0] = g2[1] = 1
inverse[0], inverse[1] = [0, 1] 

for i in range( 2, N + 1 ):
    g1[i] = ( g1[i-1] * i ) % M 
    inverse[i] = ( -inverse[M % i] * (M//i) ) % M # ai+b==0 mod M <=> i==-b*a^(-1) <=> i^(-1)==-b^(-1)*aより
    g2[i] = (g2[i-1] * inverse[i]) % M 

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


if (x+y)%3!=0:
    ans = 0
else:
    xy = (x+y)//3
    xx = y - xy
    yy = x - xy
    if xx<0 or yy<0:
        ans = 0
    else:
        ans = cmb(xx+yy, xx, M)
print(ans)

Submission status: Accepted

Solution code:
import sys
X, Y = map(int, input().split())

# たどりつけない時
if ((X+Y) % 3 != 0) or (min(X, Y)*2 < max(X, Y)):
    print(0)
    sys.exit()

# 目的地までの移動回数
n = (X+Y)//3

# 少ない方の使用回数
r = 2*n-max(X, Y)

# n個の中からr個選ぶ組み合わせ
mod = pow(10, 9)+7
bunshi = 1
bunbo = 1
for i in range(r):
    bunshi = (bunshi*(n-i)) % mod
    bunbo = (bunbo*(i+1)) % mod

ans = (bunshi*pow(bunbo, -1, mod)) % mod

print(ans)

Submission status: Accepted

Solution code:
class ModCombination:
    """
    nCk (mod m)を扱うクラス
    """

    def __init__(self, mod, n_max):
        """
        イニシャライザ
        予め 1~nの階乗と階乗の逆元を計算しておく
        :param mod: 法
        :param n_max: nの最大値(100,000で約1秒)
        """
        self.mod = mod
        self.n_max = n_max
        self.facts = [1, 1]
        self.inverses = [None, 1]
        self.fact_inverses = [1, 1]

        for i in range(2, self.n_max + 1):
            self.facts.append(self.facts[i - 1] * i % self.mod)
            # self.inverses.append(mod_inverse(i, self.mod))
            self.inverses.append(
                self.mod - self.inverses[self.mod % i] *
                (self.mod // i) % self.mod
            )
            self.fact_inverses.append(
                self.fact_inverses[i - 1] * self.inverses[i] % self.mod
            )

    def mod_combination(self, n, k):
        """
        nCk (mod m)を計算する
        :param n: n
        :param k: k
        :return: nCk (mod m)
        """
        if k > n:
            raise ValueError
        elif k == n:
            return 1
        elif k == 0:
            return 1

        denominator = self.fact_inverses[k] * self.fact_inverses[n - k] % self.mod
        return self.facts[n] * denominator % self.mod


X, Y = map(int, input().split(' '))
MOD = 10 ** 9 + 7
N_MAX = max(X, Y)

ans = 0
comb = ModCombination(mod=MOD, n_max=N_MAX)
for a in range(N_MAX + 1):
    if a > X or 2 * a > Y:
        break
    dx = X - a
    dy = Y - (2 * a)
    if dx != 2 * dy:
        continue
    b = dy

    ans += comb.mod_combination(a + b, a)
    ans %= MOD

print(ans)

Submission status: Accepted

Solution code:
X, Y = map(int, input().split())
MOD = 10**9+7
MAX = 10**6+1

 # a!のテーブルfact
fact = [0] * MAX

def comb_init():
    # 累積積のイメージ
    fact[0] = fact[1] = 1
    for i in range(2, MAX):
        fact[i] = i * fact[i-1] % MOD

def comb(n, r):
    return fact[n]*pow(fact[r], -1, MOD)*pow(fact[n-r], -1, MOD)%MOD  

if (X+Y) % 3 != 0:
    print(0)
else:
    num = (X+Y)//3
    p = (Y - X + num) // 2
    q = (X + num - Y) // 2
    if not num >= min(p, q) >= 0:
        print(0)
        exit()
    comb_init()
    print(comb(num, min(p, q)))

Submission status: Accepted

Solution code:
# nCk(mod p)の計算
from math import factorial
X, Y = map(int, input().split())
MOD = 10**9+7
MAX = 10**6+1

 # a!のテーブルfact
fact = [0] * MAX
# (a!)^-1のテーブルfinv
finv = [0] * MAX

def comb_init():
    # a!と(a!)^-1のテーブルを作る
    # 累積積のイメージ
    fact[0] = fact[1] = 1
    finv[0] = finv[1] = 1
    for i in range(2, MAX):
        fact[i] = i * fact[i-1] % MOD
        finv[i] = pow(i, -1, MOD) * finv[i-1] % MOD

def comb(n, r):
    return fact[n] * (finv[n-r] * finv[r] % MOD) % MOD    


if (X+Y) % 3 != 0:
    print(0)
else:
    num = (X+Y)//3
    p = (Y - X + num) // 2
    q = (X + num - Y) // 2
    if not num >= min(p, q) >= 0:
        print(0)
        exit()
    comb_init()
    print(comb(num, min(p, q)))

Submission status: Accepted

Solution code:
# nCk(mod p)の計算
from math import factorial
X, Y = map(int, input().split())
MOD = 10**9+7
MAX = 10**6+1

 # a!のテーブルfact
fact = [0] * MAX
# (a!)^-1のテーブルfinv
finv = [0] * MAX

def comb_init():
    # a!と(a!)^-1のテーブルを作る
    # 累積積のイメージ
    fact[0] = fact[1] = 1
    finv[0] = finv[1] = 1
    for i in range(2, MAX):
        fact[i] = i * fact[i-1] % MOD
        finv[i] = pow(i, MOD-2, MOD) * finv[i-1] % MOD

def comb(n, r):
    return fact[n] * (finv[n-r] * finv[r] % MOD) % MOD    


if (X+Y) % 3 != 0:
    print(0)
else:
    num = (X+Y)//3
    p = (Y - X + num) // 2
    q = (X + num - Y) // 2
    if not num >= min(p, q) >= 0:
        print(0)
        exit()
    comb_init()
    print(comb(num, min(p, q)))

Submission status: Accepted

Solution code:
# nCk(mod p)の計算
from math import factorial
X, Y = map(int, input().split())
MOD = 10**9+7
MAX = 10**6+1

 # a!のテーブルfact
fact = [0] * MAX
# (a!)^-1のテーブルfinv
finv = [0] * MAX

def comb_init():
    # a!と(a!)^-1のテーブルを作る
    # 累積積のイメージ
    fact[0] = fact[1] = 1
    finv[0] = finv[1] = 1
    for i in range(2, MAX):
        fact[i] = i * fact[i-1] % MOD
        finv[i] = pow(i, MOD-2, MOD) * finv[i-1] % MOD

def comb(n, r):
    return fact[n] * (finv[n-r] * finv[r] % MOD) % MOD    

n = (X+Y)//3
r = X-n
if not 0 <= r <= n:
    print(0)
    exit()

if (X+Y) % 3 != 0:
    print(0)
else:
    num = (X+Y)//3
    p = (Y - X + num) // 2
    q = (X + num - Y) // 2
    comb_init()
    print(comb(num, p))

Submission status: Accepted

Solution code:
X,Y=map(int,input().split())
mod = 10**9+7

if 2*X < Y or 2*Y < X:print(0)
elif (X+Y) % 3 != 0:print(0)
else:
  n = (X+Y) // 3
  X,Y=X-n,Y-n
  
  factorial=[1 for i in range(X+Y+1)]
  for i in range(1,X+Y+1):
    if i==1:factorial[i]=1
    else:factorial[i] = factorial[i-1]*i % mod
  print(factorial[X+Y]*pow(factorial[X]*factorial[Y],-1,mod)%mod)

Submission status: Accepted

Solution code:
def bigcmb(N, R, MOD):
    if (R < 0) or (N < R):
        return 0
    R = min(R, N - R)
    fact, inv = 1, 1
    for i in range(1, R + 1):
        fact = (fact * (N - i + 1)) % MOD
        inv = (inv * i) % MOD
    return fact * pow(inv, MOD - 2, MOD) % MOD

X, Y = map(int, input().split())
if (X + Y) % 3 != 0:
    print(0)
    exit()

mod = 10**9 + 7
count = (X + Y) // 3
ans = bigcmb(count, X - count, mod)
print(ans)

Submission status: Accepted

Solution code:
ii = lambda : int(input())
mi = lambda : map(int,input().split())
li = lambda : list(map(int,input().split()))

class com:
    def __init__(self,max, mod = 1000000007):
        self.fac = [0] * max
        self.inv = [0] * max
        self.finv = [0] * max
        self.mod = mod

        self.fac[0] = self.fac[1] = 1
        self.finv[0] = self.finv[1] = 1
        self.inv[1] = 1

        for i in range(2,max):
            self.fac[i] = self.fac[i-1] * i % mod
            self.inv[i] = mod - self.inv[mod%i] * (mod//i) % mod
            self.finv[i] = self.finv[i-1] * self.inv[i] % mod

    def com(self, n, k):
        if n < k: return 0
        if n < 0 or k < 0: return 0
        return self.fac[n] * (self.finv[k] * self.finv[n - k] % self.mod) % self.mod
    

def main():
    x,y = mi()
    if (x+y) % 3 != 0:
        print(0)
        return

    step = (x+y)//3
    if x < step or y < step:
        print(0)
        return
    
    c = com(step+1)

    ans = c.com(step, x - step)

    print(ans)

main()

Submission status: Accepted

Solution code:
X, Y = list(map(int,input().split()))

from functools import reduce

def cmb(n, r):
    INF = 10 ** 9 + 7
    r = min(n - r, r)
    if r == 0:  return 1
    numer = reduce(lambda x, y: (x * y) % INF, range(n, n - r, -1))
    denom = reduce(lambda x, y: (x * y) % INF, range(1, r + 1))
    return (numer * pow(denom, INF - 2, INF)) % INF

temp1 = 2 * X - Y
temp2 = 2 * Y - X
if temp1 % 3 or temp2 % 3:  print(0)
elif temp1 < 0 or temp2 < 0:  print(0)
else:
    a = temp1 // 3
    b = temp2 // 3
    print(cmb(a + b, a))

Submission status: Accepted

Solution code:
from numpy.linalg import solve
def C(n, r, MOD):
    num = 1
    den = 1
    for i in range(r):
        num *= n - i
        num %= MOD
        den *= i + 1
        den %= MOD
    return ((num * pow(den, MOD - 2, MOD)) % MOD)

X, Y = map(int, input().split())
MOD = 1_000_000_007
A = [[1, 2],[2, 1]]
B = [X, Y]
n, m = solve(A, B)
if n >= 0 and m >= 0 and n == int(n):
    n = int(n)
    m = int(m)
    print(C(n + m, n, MOD))
else:
    print(0)

Submission status: Accepted

Solution code:
def prepare(n, MOD):
    # 1! - n! の計算
    f = 1
    factorials = [1]  # 0!の分
    for m in range(1, n + 1):
        f *= m
        f %= MOD
        factorials.append(f)
    # n!^-1 の計算
    inv = pow(f, MOD - 2, MOD)
    # n!^-1 - 1!^-1 の計算
    invs = [1] * (n + 1)
    invs[n] = inv
    for m in range(n, 1, -1):
        inv *= m
        inv %= MOD
        invs[m - 1] = inv
     
    return factorials, invs

x, y = map(int,input().split())
if x > 2*y or y > 2*x or (x+y) % 3 != 0:
    print(0)
    exit()

d = (x+y)//3
MOD = 10**9+7
f, i = prepare(10**6, MOD)
nx = (2*y-x) // 3
print(f[d] * i[nx] % MOD * i[d-nx] % MOD)