Problem:


Score : 600 points

Problem Statement

Snuke is standing on a two-dimensional plane. In one operation, he can move by 1 in the positive x-direction, or move by 1 in the positive y-direction.

Let us define a function f(r, c) as follows:

f(r,c) :=  (The number of paths from the point (0, 0) to the point (r, c) that Snuke can trace by repeating the operation above)

Given are integers r_1, r_2, c_1, and c_2.
Find the sum of f(i, j) over all pair of integers (i, j) such that r_1 ≤ i ≤ r_2 and c_1 ≤ j ≤ c_2, and compute this value modulo (10^9+7).

Constraints

1 ≤ r_1 ≤ r_2 ≤ 10^6

1 ≤ c_1 ≤ c_2 ≤ 10^6

All values in input are integers.

Input

Input is given from Standard Input in the following format:

r_1 c_1 r_2 c_2

Output

Print the sum of f(i, j) modulo (10^9+7).

Sample Input 1

1 1 2 2

Sample Output 1

14

For example, there are two paths from the point (0, 0) to the point (1, 1): (0,0) → (0,1) → (1,1) and (0,0) → (1,0) → (1,1), so f(1,1)=2.

Similarly, f(1,2)=3, f(2,1)=3, and f(2,2)=6. Thus, the sum is 14.

Sample Input 2

314 159 2653 589

Sample Output 2

602215194



Sample input:
1 1 2 2


Sample output:
14

Submission status: Accepted

Solution code:
def convolve(a, b):
    def fft():
        d = n // 2
        v1 = w1
        v2 = w2
        v3 = w3
        while d >= 1:
            u1 = 1
            u2 = 1
            u3 = 1
            for i in range(d):
                for j in range(i, n, 2*d):
                    f1[j], f1[j+d] = (f1[j] + f1[j+d]) % p1, u1 * (f1[j] - f1[j+d]) % p1
                    f2[j], f2[j+d] = (f2[j] + f2[j+d]) % p2, u2 * (f2[j] - f2[j+d]) % p2
                    f3[j], f3[j+d] = (f3[j] + f3[j+d]) % p3, u3 * (f3[j] - f3[j+d]) % p3
                    g1[j], g1[j+d] = (g1[j] + g1[j+d]) % p1, u1 * (g1[j] - g1[j+d]) % p1
                    g2[j], g2[j+d] = (g2[j] + g2[j+d]) % p2, u2 * (g2[j] - g2[j+d]) % p2
                    g3[j], g3[j+d] = (g3[j] + g3[j+d]) % p3, u3 * (g3[j] - g3[j+d]) % p3
                u1 = u1 * v1 % p1
                u2 = u2 * v2 % p2
                u3 = u3 * v3 % p3
            v1 = v1 * v1 % p1
            v2 = v2 * v2 % p2
            v3 = v3 * v3 % p3
            d //= 2
 
    def ifft():
        d = 1
        while d < n:
            v1 = pow(invw1, n // (2 * d), p1)
            v2 = pow(invw2, n // (2 * d), p2)
            v3 = pow(invw3, n // (2 * d), p3)
            u1 = 1
            u2 = 1
            u3 = 1
            for i in range(d):
                for j in range(i, n, 2*d):
                    f1[j+d] *= u1
                    f2[j+d] *= u2
                    f3[j+d] *= u3
                    f1[j], f1[j+d] = (f1[j] + f1[j+d]) % p1, (f1[j] - f1[j+d]) % p1
                    f2[j], f2[j+d] = (f2[j] + f2[j+d]) % p2, (f2[j] - f2[j+d]) % p2
                    f3[j], f3[j+d] = (f3[j] + f3[j+d]) % p3, (f3[j] - f3[j+d]) % p3
                u1 = u1 * v1 % p1
                u2 = u2 * v2 % p2
                u3 = u3 * v3 % p3
            d *= 2
 
    p1, g1 = (11 << 21) + 1, 3
    p2, g2 = (25 << 20) + 1, 3
    p3, g3 = (27 << 20) + 1, 5
    
    n0, n1 = len(a), len(b)
    n = 1 << (max(n0, n1) - 1).bit_length() + 1
    a = a + [0] * (n-n0)
    b = b + [0] * (n-n1)
    w1 = pow(g1, (p1 - 1) // n, p1)
    w2 = pow(g2, (p2 - 1) // n, p2)
    w3 = pow(g3, (p3 - 1) // n, p3)
    invw1 = pow(w1, p1-2, p1)
    invw2 = pow(w2, p2-2, p2)
    invw3 = pow(w3, p3-2, p3)
    
    f1 = [aa % p1 for aa in a]
    f2 = [aa % p2 for aa in a]
    f3 = [aa % p3 for aa in a]
    
    g1 = [aa % p1 for aa in b]
    g2 = [aa % p2 for aa in b]
    g3 = [aa % p3 for aa in b]
    
    fft()
    for i in range(n):
        f1[i] = f1[i] * g1[i] % p1
        f2[i] = f2[i] * g2[i] % p2
        f3[i] = f3[i] * g3[i] % p3
    ifft()
    invn1 = pow(n, p1 - 2, p1)
    invn2 = pow(n, p2 - 2, p2)
    invn3 = pow(n, p3 - 2, p3)
    k1 = pow(n * p2 * p3 % p1, p1-2, p1) * p2 * p3
    k2 = pow(n * p1 * p3 % p2, p2-2, p2) * p1 * p3
    k3 = pow(n * p1 * p2 % p3, p3-2, p3) * p1 * p2
    q = p1 * p2 * p3
    return [(f1[i] * k1 + f2[i] * k2 + f3[i] * k3) % q % P for i in range(n0 + n1 - 1)]

def grow(d, v, h):
    h += [0] * d
    f = [(-1 if (i+d) % 2 else 1) * fainv[i] * fainv[d-i] % P * h[i] % P for i in range(d+1)]
    
    for idx, a in enumerate([d+1, d * fa[v-1] * fainv[v] % P, (d * fa[v-1] * fainv[v] + d + 1) % P]):
        g = [pow(a - d + i - 1, P-2, P) if i else 0 for i in range(2*d+2)]
        fg = convolve(f, g)
        p = 1
        for i in range(d+1):
            p = p * (a-i) % P
        for i in range(d+1):
            fg[d+i+1] = fg[d+i+1] * p % P
            p = p * (a+i+1) % P * pow(a-d+i, P-2, P) % P
        if idx == 1:
            for i in range(d+1):
                h[i] = h[i] * fg[d+i+1] % P
        elif idx == 0:
            for i in range(d):
                h[i+d+1] = fg[d+i+1]
        elif idx == 2:
            for i in range(d):
                h[i+d+1] = h[i+d+1] * fg[d+i+1] % P
    return h

# Create a table of the factorial of the first v+2 multiples of v, i.e., [0!, v!, 2v!, ..., (v(v+1))!]
def create_table(v):
    s = 1
    X = [1, v+1]
    while s < v:
        X = grow(s, v, X)
        s *= 2
    table = [1]
    for x in X:
        table.append(table[-1] * x % P)
    return table

def fact(i, table):
    a = table[i//v]
    for j in range(i//v*v+1, i+1):
        a = a * j % P
    return a

P = 10**9+7
v = 1 << 11
fa = [1] * (2*v+2)
fainv = [1] * (2*v+2)
for i in range(2*v+1):
    fa[i+1] = fa[i] * (i+1) % P
fainv[-1] = pow(fa[-1], P-2, P)
for i in range(2*v+1)[::-1]:
    fainv[i] = fainv[i+1] * (i+1) % P

T = create_table(v)

f = lambda a, b: fact(a+b+2, T) * pow(fact(a+1, T) * fact(b+1, T), P-2, P) % P
r1, c1, r2, c2 = map(int, input().split())
print((f(r2, c2) - f(r2, c1-1) - f(r1-1, c2) + f(r1-1, c1-1)) % P)

Submission status: Accepted

Solution code:
def convolve(a, b):
    def fft(f):
        d = n // 2
        v = w
        while d >= 1:
            u = 1
            for i in range(d):
                for j in range(i, n, 2*d):
                    f[j], f[j+d] = (f[j] + f[j+d]) % p, u * (f[j] - f[j+d]) % p
                u = u * v % p
            v = v * v % p
            d //= 2
 
    def ifft(f):
        d = 1
        while d < n:
            v = pow(invw, n // (2 * d), p)
            u = 1
            for i in range(d):
                for j in range(i, n, 2*d):
                    f[j+d] *= u
                    f[j], f[j+d] = (f[j] + f[j+d]) % p, (f[j] - f[j+d]) % p
                u = u * v % p
            d *= 2
 
    p, g = (33 << 66) + 1, 5
    n0, n1 = len(a), len(b)
    n = 1 << (max(n0, n1) - 1).bit_length() + 1
    a = a + [0] * (n-n0)
    b = b + [0] * (n-n1)
    w = pow(g, (p - 1) // n, p)
    invw = pow(w, p-2, p)
    fft(a), fft(b)
    for i in range(n):
        a[i] = a[i] * b[i] % p
    ifft(a)
    invn = pow(n, p - 2, p)
    return [a[i] * invn % p % P for i in range(n0 + n1 - 1)]

def grow(d, v, h):
    h += [0] * d
    f = [(-1 if (i+d) % 2 else 1) * fainv[i] * fainv[d-i] % P * h[i] % P for i in range(d+1)]
    
    for idx, a in enumerate([d+1, d * fa[v-1] * fainv[v] % P, (d * fa[v-1] * fainv[v] + d + 1) % P]):
        g = [pow(a - d + i - 1, P-2, P) if i else 0 for i in range(2*d+2)]
        fg = convolve(f, g)
        p = 1
        for i in range(d+1):
            p = p * (a-i) % P
        for i in range(d+1):
            fg[d+i+1] = fg[d+i+1] * p % P
            p = p * (a+i+1) % P * pow(a-d+i, P-2, P) % P
        if idx == 1:
            for i in range(d+1):
                h[i] = h[i] * fg[d+i+1] % P
        elif idx == 0:
            for i in range(d):
                h[i+d+1] = fg[d+i+1]
        elif idx == 2:
            for i in range(d):
                h[i+d+1] = h[i+d+1] * fg[d+i+1] % P
    return h

# Create a table of the factorial of the first v+2 multiples of v, i.e., [0!, v!, 2v!, ..., (v(v+1))!]
def create_table(v):
    s = 1
    X = [1, v+1]
    while s < v:
        X = grow(s, v, X)
        s *= 2
    table = [1]
    for x in X:
        table.append(table[-1] * x % P)
    return table

def fact(i, table):
    a = table[i//v]
    for j in range(i//v*v+1, i+1):
        a = a * j % P
    return a

P = 10**9+7
v = 1 << 11
fa = [1] * (2*v+2)
fainv = [1] * (2*v+2)
for i in range(2*v+1):
    fa[i+1] = fa[i] * (i+1) % P
fainv[-1] = pow(fa[-1], P-2, P)
for i in range(2*v+1)[::-1]:
    fainv[i] = fainv[i+1] * (i+1) % P

T = create_table(v)

f = lambda a, b: fact(a+b+2, T) * pow(fact(a+1, T) * fact(b+1, T), P-2, P) % P
r1, c1, r2, c2 = map(int, input().split())
print((f(r2, c2) - f(r2, c1-1) - f(r1-1, c2) + f(r1-1, c1-1)) % P)

Submission status: Accepted

Solution code:
class Combination():
    def __init__(self, n, mod):
        self.n = n
        self.mod = mod
        self.fact = self.make_fact(n)
        self.fact_inv = self.make_fact_inv(n)
    def make_fact(self, n):#0~nの階乗を求める
        res = [1]*(n+1)
        for i in range(1, n+1):
            res[i] = res[i-1]*i%self.mod
        return res
    def make_fact_inv(self, n):#0~nの階乗のmodに関する逆元を求める
        fact_inv = [1]*(n+1)
        fact_inv[n] = pow(self.fact[n], self.mod-2, self.mod)#フェルマーの小定理
        for i in range(n, 0, -1):
            fact_inv[i-1] = fact_inv[i]*i%self.mod
        return fact_inv
    def comb(self, m, k):
        return self.fact[m]*self.fact_inv[k]*self.fact_inv[m-k]%self.mod
mod = 10**9+7
r1, c1, r2, c2 = map(int, input().split())
comb = Combination(r2+c2+2, mod)
print((comb.comb(r2+c2+2, r2+1)-comb.comb(r2+c1+1, r2+1)-comb.comb(r1+c2+1, r1)+comb.comb(r1+c1, r1))%mod)

Submission status: Accepted

Solution code:
r1,c1,r2,c2 = map(int,input().split())

n = [1]*(r2+c2+3)
mod = 10**9 + 7
for i in range(r2+c2+2):
    n[i+1] = (n[i]*((i+1)%mod))%mod

def calc(r,c):
    x = n[r+c]%mod
    y = (n[r]*n[c])%mod
    return (x*(pow(y,mod-2,mod)%mod))%mod

ans = calc(r2+1,c2+1)-calc(r2+1,c1)-calc(r1,c2+1)+calc(r1,c1)
ans %= mod

print(ans)

Submission status: Accepted

Solution code:
MOD = 10**9+7

# フェルマーの小定理
def nCr(n, r, mod=MOD):
    r = min(r, n-r)
    numer = denom = 1
    for i in range(1, r+1):
        numer = numer * (n+1-i) % mod
        denom = denom * i % mod
    return numer * pow(denom, mod-2, mod) % mod

def g(r, c):
    return nCr(r+c+2, r+1) - 1

r1, c1, r2, c2 = map(int, input().split())
r1 -= 1; c1 -= 1
ans = g(r2, c2)
ans -= g(r1, c2)
ans -= g(r2, c1)
ans += g(r1, c1)
ans += MOD * 2
ans %= MOD
print(ans)

Submission status: Accepted

Solution code:
r1, c1, r2, c2 = map(int, input().split())
mod = 10 ** 9 + 7

# dp = [[0] * (r2 + 1) for _ in range(c2 + 1)]
# for i in range(c2 + 1):
#     dp[i][0] = 1
# for i in range(r2 + 1):
#     dp[0][i] = 1

# for i in range(c2):
#     for j in range(r2):
#         dp[i + 1][j + 1] = dp[i + 1][j] + dp[i][j + 1]

# ans = 0
# for i in range(c1, c2 + 1):
#     for j in range(r1, r2 + 1):
#         ans += dp[i][j]
# print(ans % mod)
# brute forceであり、TLEする。


MAX = 10 ** 6 * 2 + 5
def com_init(MAX, mod):
    fac = [0] * MAX
    finv = [0] * MAX
    inv = [0] * MAX
    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
    return fac, finv

fac, finv = com_init(MAX, mod)

def nCr(n,r):
    return fac[n] * (finv[r] * finv[n - r] % mod) % mod 

def myfunc(r, c):
    return nCr(r + c + 2, r + 1) - 1


ans = myfunc(r2, c2)
ans -= myfunc(r2, c1 - 1)
ans -= myfunc(r1 - 1, c2)
ans += myfunc(r1 - 1, c1 - 1)
print(ans % mod)

# The result is the same as the below, but much faster.
# def nCr(n, r):
#     return math.factorial(n) // (math.factorial(n - r) * math.factorial(r))

Submission status: Accepted

Solution code:
import numpy as np
import sys
read = sys.stdin.read
r1, c1, r2, c2 = map(int, read().split())
MOD = 10 ** 9 + 7


def cumprod(A, MOD=MOD):
    L = len(A)
    Lsq = int(L**.5 + 1)
    A = np.resize(A, Lsq**2).reshape(Lsq, Lsq)
    for n in range(1, Lsq):
        A[:, n] *= A[:, n - 1]
        A[:, n] %= MOD
    for n in range(1, Lsq):
        A[n] *= A[n - 1, -1]
        A[n] %= MOD
    return A.ravel()[:L]


def make_fact(U, MOD=MOD):
    x = np.arange(U, dtype=np.int64)
    x[0] = 1
    fact = cumprod(x, MOD)
    x = np.arange(U, 0, -1, dtype=np.int64)
    x[0] = pow(int(fact[-1]), MOD - 2, MOD)
    fact_inv = cumprod(x, MOD)[::-1]
    fact.flags.writeable = False
    fact_inv.flags.writeable = False
    return fact, fact_inv


fac, finv = make_fact(2 * 10**6 + 10, MOD)


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


answer = comb(r2 + c2 + 2, r2 + 1) - comb(r1 + c2 + 1, r1) - \
    comb(c1 + r2 + 1, c1) + comb(r1 + c1, r1)
answer %= MOD
print(answer)

Submission status: Accepted

Solution code:
import sys
read = sys.stdin.read
mod = 10 ** 9 + 7
r1, c1, r2, c2 = map(int, read().split())

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


fac, finv = prepare(2 * 10**6 + 10, mod)


def comb(n, k, mod=mod, fac=fac, finv=finv):
    '''
    二項係数の計算

    Parameters
    n : int
        元集合
    k : int
        元集合から選択する数
    mod : int
        あまり
    fac : list
        階乗のリスト
    finv : list
        逆元のリスト

    Returns
    c : int
        nCkの組み合わせの数
    '''
    if n < k:
        return 0
    if n < 0 or k < 0:
        return 0
    return fac[n] * (finv[k] * finv[n - k] % mod) % mod


answer = comb(r2 + c2 + 2, r2 + 1) - comb(r1 + c2 + 1, r1) - \
    comb(c1 + r2 + 1, c1) + comb(r1 + c1, r1)
answer %= mod
print(answer)

Submission status: Accepted

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

"""
まず一般に剰余込みでの組み合わせの計算。
n!, (n!)^{-1} mod pの値を配列にまとめておき、nCr = (n!)/(r!)((n-r)!)をO(1)で計算する。

max = (用意する配列の最大長)
mod = （剰余）

(n!)^{-1}の計算は¥Prod_i i^{-1}を計算して求める。
i^{-1} mod pの計算はフェルマーの小定理より、mod pにおいて
0 = p = (p // i) * i + (p % i)
0 = (p // i) + (p % i) * i^{-1}
i^{-1} = -(p // i) * (p % i)^{-1}
"""

max = 10**6 * 2 + 3 # ここでRE出しまくってた。。。
mod = 10**9+7
fact = [1, 1] # fact[n] = (n! mod p)
factinv = [1, 1] # factinv[n] = ((n!)^{-1} mod p)
inv = [0, 1] # inv[n] = (n^{-1} mod p)

for i in range(2, max+1):
    fact.append(fact[-1] * i % mod)
    inv.append(-inv[mod % i] * (mod // i) % mod)
    factinv.append(factinv[-1] * inv[-1] % mod)

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


"""
いよいよ本題。
まずは¥Sum_{0¥le i¥le x, 0¥le j¥le y} _{i+j}C_iを計算する。
実際今回の問題は容易にこれに帰着可能。

¥Sum_{0¥le i¥le x, 0¥le j¥le y} _{i+j}C_i
    = ¥Sum_i (¥Sum_j _{i+j}C_i)
    = ¥Sum_i {(T+1)^i + (T+1)^{i+1} + ... + (T+1)^{i+y})のT^iの係数}
    = ¥Sum_i {¥frac{(1+T)^{i+y+1} - (1+T)^i}{T}のT^iの係数}
    = ¥Sum_i _{i+y+1}C_{i+1}

    = ¥Sum_i _{i+y+1}C_y
    = _{y+1}C_y + _{y+2}C_y + ... + _{y+x+1}C_y
    = {(1+T)^{y+1} + (1+T)^{y+2} + ... (1+T)^{y+x+1}のT^yの係数}
    = {¥frac{(1+T)^{x+y+2} - (1+T)^{y+1}}{T}のT^yの係数}
    = _{x+y+2}C_{y+1} - 1
"""
r1, c1, r2, c2 = map(int, input().split())
a = cmb(r2+c2+2, c2+1) - 1
b = cmb(r1+c2+1, c2+1) - 1
c = cmb(r2+c1+1, r2+1) - 1
d = cmb(r1+c1, r1) - 1
ans = a - b - c + d
print(ans % mod)

Submission status: Accepted

Solution code:
#F
from operator import mul
from functools import reduce

r1, c1, r2, c2 = [int(i) for i in input().split()]
mod = 10**9 + 7

#pre-caluculation of the factorial
num = 10**6*2+3
fact=[0] * num
fact[0]=1
for i in range(1, num):
    fact[i] = (fact[i-1] * i) % mod

def combinations_count(n, r):
    r = min(r, n - r)
    numer = reduce(mul, range(n, n - r, -1), 1)
    denom = reduce(mul, range(1, r + 1), 1)
    return numer // denom

def f(rr,cc):
    #(0,0)~(r,c)までのコンビネーションの累積和
    #print(rr+cc+2, cc+1)
    #print(combinations_count(rr+cc+2, cc+1))
    #return combinations_count(rr+cc+2, cc+1) - 1
    return (fact[rr+cc+2]%mod * pow(fact[rr+1]*fact[cc+1], mod-2, mod)) % mod -1

ans = f(r2, c2) - f(r2, c1-1) - f(r1-1, c2) + f(r1-1, c1-1)
print(ans % mod)

Submission status: Accepted

Solution code:
r1,c1,r2,c2=map(int,input().split())
MOD=10**9+7
idx=r2+c2+2
perm=[1]*(idx+1)
perm_inv=[1]*(idx+1)
for i in range(1,idx+1):
    perm[i]=perm[i-1]*i
    perm[i]%=MOD
def inv_mod(a):
  return pow(a,MOD-2,MOD)
perm_inv[-1]=inv_mod(perm[-1])
for i in range(idx-1,-1,-1):
    perm_inv[i]=perm_inv[i+1]*(i+1)
    perm_inv[i]%=MOD
def comb(i,j):
    buf=perm[i+j+2]
    buf*=perm_inv[i+1]
    buf%=MOD
    buf*=perm_inv[j+1]
    buf%=MOD
    return buf
res=comb(r2,c2)
res-=comb(r2,c1-1)
res-=comb(r1-1,c2)
res+=comb(r1-1,c1-1)
print(res%MOD)

Submission status: Accepted

Solution code:
r1,c1,r2,c2=map(int,input().split())
MOD=10**9+7
idx=r2+c2+3
perm=[1]*(idx+1)
for i in range(1,idx+1):
    perm[i]=perm[i-1]*i
    perm[i]%=MOD
def inv_mod(a):
  return pow(a,MOD-2,MOD)

def comb(n,m,p=10**9+7):
    if n < m : return 0
    if n < 0 or m < 0:return 0
    m = min(m, n-m)
    top = bot = 1
    for i in range(m):
        top = top*(n-i) % p
        bot = bot*(i+1) % p
    bot = pow(bot, p-2, p)
    return top*bot % p
def g(i,j):
    return comb(i+j+2,i+1,MOD)
def s(n,m):
    return comb(n+m+2, m+1, MOD)
res=g(r2,c2)-g(r2,c1-1)-g(r1-1,c2)+g(r1-1,c1-1)
res%=MOD

ans = s(r2,c2) - s(r2, c1-1) - s(r1-1, c2) + s(r1-1, c1-1)
ans %= MOD
print(res)

Submission status: Accepted

Solution code:
m = 1000000007


r1, c1, r2, c2 = map(int, input().split())

nf = 10 ** 6 * 2 + 100
fact = [0] * (nf + 1)
fact[0] = 1
for i in range(nf):
    fact[i + 1] = fact[i] * (i + 1) % m


def F(r, c):
    path = (fact[r + c + 2] % m) * pow(fact[r + 1] * fact[c + 1], m - 2, m) % m
    return path - 1


r1 -= 1
c1 -= 1

ans = F(r2, c2)
ans -= F(r1, c2)
ans -= F(r2, c1)
ans += F(r1, c1)
ans = ans % m

print(ans)

Submission status: Accepted

Solution code:
#0<=i<r,0<=j<cで総和求めて引く
#chooseの+2でよい
mod = 10**9+7

def chs(a,b):
    a+=1;b+=1
    a+=b
    res = 1
    for i in range(a,a-b,-1):
        res *= i 
        res%=mod
    for i in range(1,b+1):
        res *= rev[i]
        #print(rev[i],pow(i,mod-2,mod))
        res %=mod 
    return res


r1,c1,r2,c2 = map(int, input().split( ))
r1 -=1;c1-=1
if c2>r2:
    r2,c2 = c2,r2
    r1,c1= c1,r1
rev = [pow(i,mod-2,mod) for i in range(c2+5)]###
ans = chs(r2,c2)-chs(r1,c2)-chs(r2,c1)+chs(r1,c1)
ans%=mod
#print(chs(r2,c2),chs(r1,c2),chs(r2,c1),chs(r1,c1))

print(ans)

Submission status: Accepted

Solution code:
r1,c1,r2,c2=map(int, raw_input().split())

N=r2+c2+1
mod=10**9+7
fact, inv_fact = [1], [1]
fact_tmp = 1
for i in range(1, N+1):
    fact_tmp *= i
    fact_tmp %= mod
    fact.append(fact_tmp)
    inv_fact.append(pow(fact_tmp, mod-2, mod))
 
def ncr(n,r):
	if n < 0 or r < 0 or n < r:	return 0
	else:	return (fact[n] * inv_fact[r] * inv_fact[n-r]) %mod

ans=0
for r in range(r1,r2+1):
    ans+=ncr(r+c2+1,r+1)-ncr(r+c1,r+1)
    ans%=mod

print ans

Submission status: Accepted

Solution code:
MOD = 10**9+7
p= []
rp = []

def g(r,c):
    ans = 0
    if r > c:
        r,c = c,r
    for i in range(r+1):
        ans += f(i+1,c)
        ans %= MOD
    return ans

def f(r,c):
    return (p[r+c] * rp[r] * rp[c]) % MOD

def extgcd(a,b):
    r = [1, 0, a]
    w = [0, 1, b]
    while w[2] != 1:
        q = r[2]//w[2]
        ra = w
        wa = [r[0]-q*w[0], r[1]-q*w[1], r[2]-q*w[2]]
        r = ra
        w = wa
    #[x,y]
    return [w[0], w[1]]

def mod_inv(a,m):
    x = extgcd(a, m)[0]
    return (m+x%m)%m

r1,c1, r2,c2 = map(int,input().split())
p = [0 for _ in range(r2+c2+3)]
rp = [0 for _ in range(max(r2,c2)+2)]

p[0] = 1
p[1] = 1
rp[0] = 1
rp[1] = 1
for i in range(2,c2+r2+3):
    p[i] = (p[i-1] * i) % MOD

for i in range(2,max(r2,c2)+2):
    rp[i] = mod_inv(p[i], MOD)

ans = g(r2,c2) - g(r1-1,c2) - g(r2,c1-1) + g(r1-1,c1-1)
ans %= MOD
print (ans)

Submission status: Accepted

Solution code:
import sys
import math
from collections import defaultdict

sys.setrecursionlimit(10**7)
def input():
    return sys.stdin.readline()[:-1]

mod = 10**9 + 7

def I(): return int(input())
def LI(): return list(map(int, input().split()))
def LIR(row,col):
    if row <= 0:
        return [[] for _ in range(col)]
    elif col == 1:
        return [I() for _ in range(row)]
    else:
        read_all = [LI() for _ in range(row)]
        return map(list, zip(*read_all))

#################

# 0!~n!をmodしつつ求める
def fact_all(n,M=mod):
    f = [1]*(n+1)
    ans = 1
    for i in range(1,n+1):
        ans = (ans*i)%M
        f[i] = ans
    return f

# inv(0!)~inv(n!)をmodしつつ求める
def fact_inv_all(fact_all,M=mod):
    N = len(fact_all)
    finv = [0]*N
    finv[-1] = pow(fact_all[-1],M-2,M)
    for i in range(N-1)[::-1]:
        finv[i] = finv[i+1]*(i+1)%M
    return finv

# nCkをmodしつつ返す
def nCk(n,k,fact_list=[],inv_list=[],M=mod):
    # a!をmodしつつ求める
    def fact(a,M=mod):
        ans = 1
        for i in range(2,a+1):
            ans = (ans*i)%M
        return ans

    # 互いに素なa,bについて、a*x+b*y=1の一つの解[x,y]を出力
    def extgcd(a,b):
        r = [1,0,a]
        w = [0,1,b]
        while w[2] != 1:
            q = r[2]//w[2]
            r2 = w
            w2 = [r[0]-q*w[0],r[1]-q*w[1],r[2]-q*w[2]]
            r = r2
            w = w2
        return [w[0],w[1]]

    # aの逆元(mod M)を求める（aとMは互いに素）
    def mod_inv(a,M=mod):
        x = extgcd(a,M)[0]
        return (M+x%M)%M
    
    if fact_list and inv_list:
        return (((fact_list[n]*inv_list[k])%M)*inv_list[n-k])%M
    else:
        x = fact(n,M)
        y1 = mod_inv(fact(k,M),M)
        y2 = mod_inv(fact(n-k,M),M)
        return ((x*y1)%M*y2)%M


def g(r,c):
    retval = 0
    for i in range(r+1):
        retval += nCk(i+c+1,c,fact_list,inv_list)
        retval %= mod
    return retval

r1,c1,r2,c2 = LI()
fact_list = fact_all(r2+c2+1)
inv_list = fact_inv_all(fact_list)

print((g(r2,c2)-g(r2,c1-1)-g(r1-1,c2)+g(r1-1,c1-1))%mod)

Submission status: Accepted

Solution code:
r1, c1, r2, c2 = map(int, input().split())
mod = int(1e+9) + 7
def inved(x):
  a, b, c, d, k, l = 1, 0, 0, 1, x, mod
  while l != 0:
    a, b, c, d = c, d, a - c * (k // l), b - d * (k // l)
    k, l = l, k % l
  return a % mod
frac = [1]
for i in range(r2 + c2 + 2):
  frac.append(((i+1) * frac[i]) % mod)
fracr2c2 = frac[r2 + c2 + 2]
fracr1c2 = frac[r1 + c2 + 1]
fracr2c1 = frac[r2 + c1 + 1]
fracr1c1 = frac[r1 + c1]
fracr2 = frac[r2 + 1]
fracr1 = frac[r1]
fracc2 = frac[c2 + 1]
fracc1 = frac[c1]
g = 0
g += (fracr2c2 * inved(fracr2) * inved(fracc2)) % mod
g %= mod
g += (fracr1c1 * inved(fracr1) * inved(fracc1)) % mod
g %= mod
g -= (fracr1c2 * inved(fracr1) * inved(fracc2)) % mod
g %= mod
g -= (fracr2c1 * inved(fracr2) * inved(fracc1)) % mod
g %= mod
print(g)

Submission status: Accepted

Solution code:
from operator import mul
from functools import reduce

def comb(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 = 3 * 10**6
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 )
    
    
    
r1, c1, r2, c2 = [int(i) for i in input().split()]
 
def calc(r, c):
    a = comb(r + c + 2, r + 1, mod) - r - c - 2
    b = r * (r + 3) / 2
 
    if c == 1:
        return b
    else:
        return a
 
result = calc(r2, c2) - calc(r2, c1 - 1) - calc(r1 - 1, c2) + calc(r1 - 1, c1 - 1)
result %= mod
if result < 0:
  result += mod
print(result)

Submission status: Accepted

Solution code:
import sys
import socket

hostname = socket.gethostname()

if hostname == 'F451C':
    sys.stdin = open('f1.in')


def read_int_list():
    return list(map(int, input().split()))


def read_str_list():
    return input().split()


def read_int():
    return int(input())


def read_str():
    return input()


M = 10 ** 9 + 7
f = [1] * (2*10**6+4)
for i in range(1, 2*10**6+3):
  f[i] = f[i-1] * i
  f[i] %= M


def g(r, s):
  res = 1
  frs = f[r+s+2]
  fs = f[s+1]
  fr = f[r+1]

  res *= pow(fr, M-2, M)
  res *= pow(fs, M-2, M)

  res *= frs
  res %= M
  return res


def main():
    r1, c1, r2, c2 = read_int_list()
    res = 0
    res += g(r2, c2) - g(r2, c1-1) - g(r1-1, c2) + g(r1-1, c1-1)
    res %= M
    print(res)


main()

Submission status: Accepted

Solution code:
MOD = 10**9+7
def inv_mod(a,p=MOD):
    def inv_mod_sub(a,p):
        if a == 1:
            return 1,0
        else:
            d,r = p//a,p%a
            x,y = inv_mod_sub(r,a)
            return y-d*x,x
    if p < 0: p = -p
    a %= p
    return inv_mod_sub(a,p)[0] % p

def comb_mod(n,k):
    if k < 0 or k > n:
        return 0
    else:
        return f_mod[n]*f_mod_inverse[k]*f_mod_inverse[n-k] % MOD

def f(a,b):
  return comb_mod(a+b,b)

r1,c1,r2,c2 = map(int,input().split())
f_mod=[1]*(3*10**6)
f_mod_inverse=[1]*(3*10**6)
for i in range(1,3*10**6):
  f_mod[i]=f_mod[i-1]*i%MOD
  f_mod_inverse[i]=f_mod_inverse[i-1]*inv_mod(i)%MOD
print((f(r2+1,c2+1)-f(r1,c2+1)-f(r2+1,c1)+f(r1,c1))%MOD)

Submission status: Accepted

Solution code:
import sys
import numpy as np

sys.setrecursionlimit(10 ** 7)

r1, c1, r2, c2 = map(int, input().split())


# 階乗、Combinationコンビネーション(numpyを使う)

def cumprod(arr, MOD):
    L = len(arr)
    Lsq = int(L**.5+1)
    arr = np.resize(arr, Lsq**2).reshape(Lsq, Lsq)
    for n in range(1, Lsq):
        arr[:, n] *= arr[:, n-1]
        arr[:, n] %= MOD
    for n in range(1, Lsq):
        arr[n] *= arr[n-1, -1]
        arr[n] %= MOD
    return arr.ravel()[:L]


def make_fact(U, MOD):
    x = np.arange(U, dtype=np.int64)
    x[0] = 1
    fact = cumprod(x, MOD)
    x = np.arange(U, 0, -1, dtype=np.int64)
    x[0] = pow(int(fact[-1]), MOD-2, MOD)
    fact_inv = cumprod(x, MOD)[::-1]
    return fact, fact_inv


MOD = 10 ** 9 + 7
U = 10**6 * 2 + 10
fact, fact_inv = make_fact(U, MOD)


def mod_comb_k(n, k, mod):
    return fact[n] * fact_inv[k] % mod * fact_inv[n - k] % mod


def calc_rc(r, c):
    a = mod_comb_k(r + c + 2, r + 1, MOD)
    b = 1
    return a-b


ans = calc_rc(r2, c2) + calc_rc(r1-1, c1-1) - \
    calc_rc(r1-1, c2) - calc_rc(r2, c1-1)
ans %= MOD

print(ans)

Submission status: Accepted

Solution code:
#!/usr/bin/env python3
import sys
INF = float("inf")

MOD = 1000000007  # type: int


class Combination(object):

    def __init__(self, N, mod=10**9+7):
        fac, finv, inv = [0]*(N+1), [0]*(N+1), [0]*(N+1)
        fac[:2] = 1, 1
        finv[:2] = 1, 1
        inv[1] = 1
        for i in range(2, N+1):
            fac[i] = fac[i-1]*i % mod
            inv[i] = -inv[mod % i]*(mod//i) % mod
            finv[i] = finv[i-1]*inv[i] % mod
        self.N = N
        self.MOD = mod
        self.fac = fac
        self.finv = finv
        self.inv = inv

    def __call__(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 solve(r: "List[int]", c: "List[int]"):

    cmb = Combination(r[1]+c[1]+2, mod=MOD)

    def g(x, y):
        return cmb(x+y+2, y+1)-1

    ans = g(r[1], c[1])-g(r[0]-1, c[1])-g(r[1], c[0]-1)+g(r[0]-1, c[0]-1)
    print(ans % MOD)
    return


def main():

    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    r = [int()] * (2)  # type: "List[int]"
    c = [int()] * (2)  # type: "List[int]"
    for i in range(2):
        r[i] = int(next(tokens))
        c[i] = int(next(tokens))
    solve(r, c)


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
#!/usr/bin/env python3
import sys
INF = float("inf")

MOD = 1000000007  # type: int


class Combination(object):

    def __init__(self, N, mod=10**9+7):
        fac, finv, inv = [0]*(N+1), [0]*(N+1), [0]*(N+1)
        fac[:2] = 1, 1
        finv[:2] = 1, 1
        inv[1] = 1
        for i in range(2, N+1):
            fac[i] = fac[i-1]*i % mod
            inv[i] = -inv[mod % i]*(mod//i) % mod
            finv[i] = finv[i-1]*inv[i] % mod
        self.N = N
        self.MOD = mod
        self.fac = fac
        self.finv = finv
        self.inv = inv

    def __call__(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 solve(r: "List[int]", c: "List[int]"):

    cmb = Combination(r[1]+c[1]+1, mod=MOD)

    def f(x, y):
        return cmb(x+y, y)

    def g(x, y):
        return f(x+1, y)+f(x, y+1)-1

    ans = g(r[1], c[1])-g(r[0]-1, c[1])-g(r[1], c[0]-1)+g(r[0]-1, c[0]-1)
    print(ans % MOD)
    return


def main():

    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    r = [int()] * (2)  # type: "List[int]"
    c = [int()] * (2)  # type: "List[int]"
    for i in range(2):
        r[i] = int(next(tokens))
        c[i] = int(next(tokens))
    solve(r, c)


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
#!/usr/bin/env python3
from collections import defaultdict,deque
from heapq import heappush, heappop
from bisect import bisect_left, bisect_right
import sys, random, itertools, math
sys.setrecursionlimit(10**5)
input = sys.stdin.readline
sqrt = math.sqrt
def LI(): return list(map(int, input().split()))
def LF(): return list(map(float, input().split()))
def LI_(): return list(map(lambda x: int(x)-1, input().split()))
def II(): return int(input())
def IF(): return float(input())
def LS(): return list(map(list, input().split()))
def S(): return list(input().rstrip())
def IR(n): return [II() for _ in range(n)]
def LIR(n): return [LI() for _ in range(n)]
def FR(n): return [IF() for _ in range(n)]
def LFR(n): return [LI() for _ in range(n)]
def LIR_(n): return [LI_() for _ in range(n)]
def SR(n): return [S() for _ in range(n)]
def LSR(n): return [LS() for _ in range(n)]
mod = 1000000007
inf = 1e10

# solve
# 解説AC
# f(r + 1, c) = f(r, 0) + f(r, 1) + ... + f(r, c)
# 図はこう
# .....147
# .....258
# .....369
# .....ACE
# .....BDF
# 4の通りはf(1)+f(2)+f(3)+f(A)+(B)
# てことはf(1)+f(2)+f(3) = f(4) - f(A) - f(B)
# さらにf(A)+f(B)=f(C)　なんで
# f(1)+f(2)+f(3) = f(4)-f(C)
# これを繰り返すだけ
# easy
def solve():
    def cmb(n, k):
        return fact[n] * invfact[k] * invfact[n-k] % mod
    maxn = int(3e6 + 10)
    r1, c1, r2, c2 = LI()
    ans = 0
    fact = [i for i in range(maxn)]
    fact[0] = 1
    invfact = [i+1 for i in range(maxn)]
    invfact[0] = 1
    for i in range(1, maxn-1):
        fact[i + 1] *= fact[i]
        fact[i + 1] %= mod
    invfact[-1] = pow(fact[-1], mod - 2, mod)
    invr1 = pow(r1, mod - 2, mod)
    for i in range(maxn - 2, -1, -1):
        invfact[i] *= invfact[i + 1]
        invfact[i] %= mod
    acc = list(map(lambda x: x % mod, itertools.accumulate(fact)))
    for c in range(c1, c2 + 1):
        ans += cmb(c + r2 + 1, c + 1) - cmb(c + r1 , c + 1)
        ans %= mod
    print(ans)
    return


#main
if __name__ == '__main__':
    solve()

Submission status: Accepted

Solution code:
M=1000000007
r1,c1,r2,c2=map(int,input().split())
n=r2+c2+2
fac=[1]+[0]*n
for i in range(1,n+1):fac[i]=fac[i-1]*i%M
f=lambda r,c:fac[r+c+2]*pow(fac[c+1],M-2,M)*pow(fac[r+1],M-2,M)-1
print((f(r2,c2)-f(r2,c1-1)-f(r1-1,c2)+f(r1-1,c1-1))%M)