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:
import sys

readline = sys.stdin.readline
MOD = 10 ** 9 + 7
INF = float('INF')
sys.setrecursionlimit(10 ** 5)


def main():
    r1, c1, r2, c2 = map(int, readline().split())

    def calc(c):
        prev = 1
        cur = 1
        comb1 = 0
        comb2 = 0

        for i in range(1, r1 + 1):
            cur = prev * (c + i)
            cur %= MOD
            cur *= pow(i, MOD - 2, MOD)
            cur %= MOD
            comb1 += cur
            comb1 %= MOD
            prev = cur

        comb2 = comb1

        for i in range(r1 + 1, r2 + 2):
            cur = prev * (c + i)
            cur %= MOD
            cur *= pow(i, MOD - 2, MOD)
            cur %= MOD
            comb2 += cur
            comb2 %= MOD
            prev = cur

        return comb1, comb2

    comb1, comb2 = calc(c1-1)
    comb3, comb4 = calc(c2)

    ans = comb4 - comb2 - comb3 + comb1
    ans %= MOD
    print(ans)


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
mod = 10**9+7
def cmb(n,k):
    return fac[n]*inv_fac[n-k]*inv_fac[k] % mod
def g(r,c):
    x = 0
    for i in range(1,r+2):
        x += cmb(c+i,i)
    x %= mod
    return x

r1,c1,r2,c2 = map(int,input().split())
N = r2+c2+1
fac = [1]
for i in range(1,N+1):
    fac.append(fac[-1]*i % mod)
inv_fac = [pow(fac[N],mod-2,mod)]
for i in range(1,N+1)[::-1]:
    inv_fac.append(inv_fac[-1]*i % mod)
inv_fac = inv_fac[::-1]
print((g(r2,c2)-g(r2,c1-1)-g(r1-1,c2)+g(r1-1,c1-1))% mod)

Submission status: Accepted

Solution code:
import sys
from collections import *
import heapq
import math
import bisect
from itertools import permutations,accumulate,combinations,product
from fractions import gcd
def input():
    return sys.stdin.readline()[:-1]
mod=10**9+7

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

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

    N = 10**6*2+2
    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 g(r,c):
        tmp=cmb(r+1+c+1,r+1)-1
        return tmp%mod

    ans=0
    ans+=g(r2,c2)
    ans-=g(r2,c1-1)
    ans-=g(r1-1,c2)
    ans+=g(r1-1,c1-1)
    ans%=mod
    print(ans)
main()

Submission status: Accepted

Solution code:
import sys
from collections import *
import heapq
import math
import bisect
from itertools import permutations,accumulate,combinations,product
from fractions import gcd
def input():
    return sys.stdin.readline()[:-1]
mod=10**9+7

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

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

N = 10**6*2+2
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 g(r,c):
    tmp=cmb(r+1+c+1,r+1)-1
    return tmp%mod

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

Submission status: Accepted

Solution code:
import sys
from collections import *
import heapq
import math
import bisect
from itertools import permutations,accumulate,combinations,product
from fractions import gcd
def input():
    return sys.stdin.readline()[:-1]
mod=10**9+7

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

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

N = 10**6*2+10
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 g(r,c):
    tmp=cmb(r+1+c+1,r+1)-1
    return tmp%mod

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

Submission status: Accepted

Solution code:
import sys
from collections import *
import heapq
import math
import bisect
from itertools import permutations,accumulate,combinations,product
from fractions import gcd
def input():
    return sys.stdin.readline()[:-1]
mod=10**9+7

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

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

N = 10**6*2+10
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 g(r,c):
    tmp=cmb(r+1+c+1,r+1)-cmb(0+c+1,0)
    return tmp%mod

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

Submission status: Accepted

Solution code:
import sys
from collections import *
import heapq
import math
import bisect
from itertools import permutations,accumulate,combinations,product
from fractions import gcd
def input():
    return sys.stdin.readline()[:-1]
mod=10**9+7

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

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

N = 10**6*2+10
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 g(r,c):
    tmp=0
    for i in range(1,r+2):
        tmp+=cmb(i+c,i)
        tmp%=mod
    return tmp

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

Submission status: Accepted

Solution code:
import math

r1, c1, r2, c2 = map(int, input().split())
P = int(1e9+7)
kaizyo = [0]
kaizyo_inv = [0]
tmp = 1
for i in range(1, 2*max(r1, r2, c1, c2)+2):
    tmp = (tmp*i) % P
    kaizyo.append(tmp)
    kaizyo_inv.append(pow(tmp, P - 2, P))


def comb(n, r):
    if n < r or n==0:
        return 0
    elif n == r or r==0:
        return 1
    else:
        return kaizyo[n] * kaizyo_inv[r] * kaizyo_inv[n - r]


def solve_naive(r, c):
    if r < 0 or c < 0:
        return 0
    S = [[0] * (c+1) for _ in range(r+1)]
    for i in range(1, r + 1):
        for j in range(1, c + 1):
            S[i][j] = S[i - 1][j] + S[i][j - 1] - S[i - 1][j - 1] + comb(i + j , i)
    return S[-1][-1]


def solve(r, c):
    if r < 0 or c < 0:
        return 0
    ret = 0
    for i in range(2, r + 2):
        ret = (ret + comb(i + c, i)) % P
    return ret


# solve = solve_naive
ans = (solve(r2, c2) - solve(r1 - 1, c2) -
       solve(r2, c1 - 1) + solve(r1 - 1, c1 - 1)) % P
print(ans)

Submission status: Accepted

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

MOD = 10 ** 9 + 7
N = r2 + c2 + 10
fact = [0 for _ in range(N)]
invfact = [0 for _ in range(N)]
fact[0] = 1
for i in range(1, N):
    fact[i] = fact[i - 1] * i % MOD

invfact[N - 1] = pow(fact[N - 1], MOD - 2, MOD)

for i in range(N - 2, -1, -1):
    invfact[i] = invfact[i + 1] * (i + 1) % MOD
def nCk(n, k):
    if k < 0 or n < k:
        return 0
    else:
        return fact[n] * invfact[k] * invfact[n - k] % MOD
        
ans = nCk(r2 + c2 + 2, r2 + 1) - nCk(r2 + c1 + 1, r2 + 1) \
    - nCk(r1 + c2 + 1, c2 + 1) + nCk(r1 + c1, r1)
print(ans % MOD)

Submission status: Accepted

Solution code:
r1,c1,r2,c2 = map(int, input().split())
mod = int(1e9+7)

# f(i,j) = cmb(i+j,i)

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

def init_cmb(Nmax):
    #mod = 10**9+7 #出力の制限
    g1 = [1, 1] # 元テーブル
    g2 = [1, 1] # 逆元テーブル
    inverse = [0, 1] #逆元テーブル計算用テーブル

    for i in range(2, Nmax + 1):
        g1.append((g1[-1] * i) % mod)
        inverse.append((-inverse[mod % i] * (mod//i)) % mod)
        g2.append((g2[-1] * inverse[-1]) % mod)
    return g1, g2
  
g1, g2 = init_cmb(max(r1,r2) + max(c1,c2) + 10)

def solve(r1,c1,r2,c2):
  def f(r,c):
    return cmb(r+c,min(r,c))
  
  res = 0
  # S[r2,c2] - S[r2,c1-1] - S[r1-1,c2] + S[r1-1,c1-1]
  # S[r2,c2] = cmb(r2,0) + cmb(r2+1,1) + ... + cmb(r2+c2, c2)
  r2,c2 = r2, c2
  res += f(r2,c2)
  res -= f(r2,c1)
  res -= f(r1,c2)
  res += f(r1,c1)
  
  """
  for c in range(0,c2+1):
    res += (c+1) * cmb(r2+c, c)
    res %= mod
  for c in range(0,c1):
    res -= (c+1) * cmb(r2+c, c)
    res %= mod
  for r in range(0,r1):
    res -= (r+1) * cmb(c2+r,r)
    res %= mod
  for r in range(0,r1):
    res += (r+1) * cmb(c1-1+r,r)
    res %= mod
  """  
  return res % mod

def solve2(r1,c1,r2,c2):
  res = 0
  for r in range(r1,r2+1):
    for c in range(c1,c2+1):
      res += cmb(c+r,c)
      res %= mod
  return res

#print(solve(r1,c1,r2,c2))
print(solve(r1,c1,r2+1,c2+1))
#print(solve2(r1,c1,r2,c2))

Submission status: Accepted

Solution code:

class Combination:
    def __init__(self, n_max, mod=10 ** 9 + 7):
        # O(n_max + log(mod))
        self.mod = mod
        f = 1
        self.fac = fac = [f]
        for i in range(1, n_max + 1):
            f = f * i % mod
            fac.append(f)
        f = pow(f, mod - 2, mod)
        self.facinv = facinv = [f]
        for i in range(n_max, 0, -1):
            f = f * i % mod
            facinv.append(f)
        facinv.reverse()

    # "n 要素" は区別できる n 要素
    # "k グループ" はちょうど k グループ

    def __call__(self, n, r):  # self.C と同じ
        return self.fac[n] * self.facinv[r] % self.mod * self.facinv[n - r] % self.mod

    def nCr(self, n, r):
        if not 0 <= r <= n:
            return 0
        return self.fac[n] * self.facinv[r] % self.mod * self.facinv[n - r] % self.mod


def resolve():
    def f(r, c):
        return cmb.nCr(r + c, r)

    MOD = 10 ** 9 + 7
    r1, c1, r2, c2 = map(int, input().split())
    r2 += 1
    c2 += 1
    cmb = Combination(r2 + c2 + 5)

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


if __name__ == "__main__":
    resolve()

Submission status: Accepted

Solution code:
# nCr mod m
# rがn/2に近いと非常に重くなる
def combination(n, r, mod=10**9+7):
    n1, r = n+1, min(r, n-r)
    numer = denom = 1
    for i in range(1, r+1):
        numer = numer * (n1-i) % mod
        denom = denom * i % mod
    return numer * pow(denom, mod-2, mod) % mod

mod = 10**9 + 7
r1, c1, r2, c2 = map(int, input().split())
r2 += 1
c2 += 1
a1 = combination(r1+c1, r1)
a2 = combination(r2+c2, r2)
a3 = combination(r1+c2, r1)
a4 = combination(r2+c1, r2)
print((a1+a2-a3-a4)%mod)

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.buffer.readline

#sys.setrecursionlimit(10**9)
#from functools import lru_cache

def RD(): return input().rstrip().decode()
def II(): return int(input())
def FI(): return int(input())
def MI(): return map(int,input().split())
def MF(): return map(float,input().split())
def LI(): return list(map(int,input().split()))
def LF(): return list(map(float,input().split()))
def TI(): return tuple(map(int,input().split()))
# rstrip().decode()


def main():
	r1,c1,r2,c2=MI()
	m=10**9+7

	ff=[1]

	for i in range(1,2*10**6+5):
		ff.append(ff[-1]*i%m)


	def f(r,c):
		return (ff[r+c]*pow(ff[r],m-2,m)*pow(ff[c],m-2,m))%m

	ans=0
	ans+=f(r2+1,c2+1)
	ans+=f(r1,c1)
	ans-=f(r2+1,c1)
	ans-=f(r1,c2+1)

	print(ans%m)



if __name__ == "__main__":
	main()

Submission status: Accepted

Solution code:
a1,b1,a2,b2=map(int,input().split())

import sys
sys.setrecursionlimit(2000000000)

p = 10 ** 9 + 7
N = a2+b2+2  # N は必要分だけ用意する
R = max(a2+1,b2+1)
fact = [1, 1]  # fact[n] = (n! mod p)
factinv = [1, 1]  # factinv[n] = ((n!)^(-1) mod p)
inv = [0, 1]  # factinv 計算用

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

def comb(n, r, p):
  if (r < 0) or (n < r):
    return 0
  r = min(r, n - r)
  return fact[n] * factinv[r] * factinv[n-r] % p

score=comb(a2+b2+2,a2+1,p)-comb(a2+b1+1,a2+1,p)-comb(a1+b2+1,a1,p)+comb(a1+b1,a1,p)
print(score%(10**9+7))

Submission status: Accepted

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

mod = 10**9+7
MAX_N = 3*10**6

fact = [1]
fact_inv = [0]*(MAX_N+4)
for i in range(MAX_N+3):
    fact.append(fact[-1]*(i+1)%mod)

fact_inv[-1] = pow(fact[-1],mod-2,mod)
for i in range(MAX_N+2,-1,-1):
    fact_inv[i] = fact_inv[i+1]*(i+1)%mod

def comb(n,k,mod=mod):
    if n<k:return 0
    return fact[n] * fact_inv[k] % mod * fact_inv[n-k] %mod

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

print(ans)

Submission status: Accepted

Solution code:
MOD = 10 ** 9 + 7
table_len = 2 * 10 ** 6 + 10

fac = [1, 1]
for i in range(2, table_len):
    fac.append(fac[-1] * i % MOD)
    
finv = [0] * table_len
finv[-1] = pow(fac[-1], MOD - 2, MOD)
for i in range(table_len-1, 0, -1):
    finv[i-1] = finv[i] * i % MOD

def comb(a, b):
    return fac[a+b] * finv[a] * finv[b] % MOD


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

Submission status: Accepted

Solution code:

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

MAX = 2 * 10 ** 6 + 1
MOD = 10 ** 9 + 7

# Factorial
fac = [0] * (MAX + 1)
fac[0] = 1
fac[1] = 1

# Inverse
inv = [0] * (MAX + 1)
inv[1] = 1

# Inverse factorial
finv = [0] * (MAX + 1)
finv[0] = 1
finv[1] = 1

for i in range(2, MAX + 1):
    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 f(r, c):
    return fac[r + c] * finv[r] * finv[c] % MOD


ans = 0
for i in range(c1, c2 + 1):
    ans += f(r2, i + 1) - f(r1 - 1, i + 1)
    ans %= MOD
print(ans)

Submission status: Accepted

Solution code:
'''
研究室PCでの解答
解説AC
'''
import math
#import numpy as np
import queue
import bisect
from collections import deque,defaultdict
import heapq as hpq
from sys import stdin,setrecursionlimit
#from scipy.sparse.csgraph import dijkstra
#from scipy.sparse import csr_matrix
ipt = stdin.readline
setrecursionlimit(10**7)
mod = 10**9+7

def main():
    r1,c1,r2,c2 = map(int,ipt().split())
    #nCrをmodで割った余りを求める。Nに最大値を入れて使用。
    N = r2+c2+2
    g1 = [1, 1] # 元テーブル
    g2 = [1, 1] #逆元テーブル
    inverse = [0, 1] #逆元テーブル計算用テーブル
    def cmb(n,r,mod=(10**9+7)):
        if r<0 or r>n :
            return 0
        r = min(r,n-r)
        return g1[n]*g2[r]*g2[n-r]%mod
    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)

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

    return None

if __name__ == '__main__':
    main()

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

def func(r, c):
    return f[r+c] * i[r] % MOD * i[c] % MOD

MOD = 10**9+7
f, i = prepare(2*10**6 + 2, MOD)


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

combi = func(r2+1, c2+1) - func(r2+1, c1) - func(r1, c2+1) + func(r1, c1)
print(combi % MOD)

Submission status: Accepted

Solution code:
import copy


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

def func(r, c):
    return f[r+1+c+1] * i[r+1] % MOD * i[c+1] % MOD

MOD = 10**9+7
f, i = prepare(2*10**6 + 2, MOD)


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

combi = func(r2, c2) - func(r2, c1-1) - func(r1-1, c2) + func(r1-1, c1-1)
print(combi % MOD)

Submission status: Accepted

Solution code:
class Combination:
    """
  O(n)の前計算を1回行うことで，O(1)でnCr mod mを求められる
  n_max = 10**6のとき前処理は約950ms (PyPyなら約340ms, 10**7で約1800ms)
  使用例：
  comb = Combination(1000000)
  print(comb(5, 3))  # 10
  """

    def __init__(self, n_max, mod=10 ** 9 + 7):
        self.mod = mod
        self.modinv = self.make_modinv_list(n_max)
        self.fac, self.facinv = self.make_factorial_list(n_max)

    def __call__(self, n, r):
        if n < r or n < 0 or r < 0:
            return 0
        return self.fac[n] * self.facinv[r] % self.mod * self.facinv[n - r] % self.mod

    def make_factorial_list(self, n):
        # 階乗のリストと階乗のmod逆元のリストを返す O(n)
        # self.make_modinv_list()が先に実行されている必要がある
        fac = [1]

        facinv = [1]
        for i in range(1, n + 1):
            fac.append(fac[i - 1] * i % self.mod)
            facinv.append(facinv[i - 1] * self.modinv[i] % self.mod)
        return fac, facinv

    def make_modinv_list(self, n):
        # 0からnまでのmod逆元のリストを返す O(n)
        modinv = [0] * (n + 1)
        modinv[1] = 1
        for i in range(2, n + 1):
            modinv[i] = self.mod - self.mod // i * \
                modinv[self.mod % i] % self.mod
        return modinv


MOD = 10**9 + 7

r1, c1, r2, c2 = map(int, input().split())
c = Combination(2000006)
ans = 0
for r in range(r1, r2 + 1):
    temp = c(c2 + r + 1, r + 1) - c(c1 + r + 1 - 1, r + 1)
    temp %= MOD
    ans += temp
    ans %= MOD
print(ans)

Submission status: Accepted

Solution code:
a,b,c,d=map(int,input().split())
m=10**9+7
def f(r,c):
 s=t=1
 for i in range(c):s=s*(r+c-i)%m;t=t*-~i%m
 return s*pow(t,m-2,m)
print((f(a,b)-f(c+1,b)-f(a,d+1)+f(c+1,d+1))%m)

Submission status: Accepted

Solution code:
import sys,bisect,string,math,time,functools,random,fractions
from heapq import heappush,heappop,heapify
from collections import deque,defaultdict,Counter
from itertools import permutations,combinations,groupby
rep=range;R=range
def Golf():n,*t=map(int,open(0).read().split())
def I():return int(input())
def S_():return input()
def IS():return input().split()
def LS():return [i for i in input().split()]
def MI():return map(int,input().split())
def LI():return [int(i) for i in input().split()]
def LI_():return [int(i)-1 for i in input().split()]
def NI(n):return [int(input()) for i in range(n)]
def NI_(n):return [int(input())-1 for i in range(n)]
def StoLI():return [ord(i)-97 for i in input()]
def ItoS(n):return chr(n+97)
def LtoS(ls):return ''.join([chr(i+97) for i in ls])
def RA():return map(int,open(0).read().split())
def GI(V,E,ls=None,Directed=False,index=1):
    org_inp=[];g=[[] for i in range(V)]
    FromStdin=True if ls==None else False
    for i in range(E):
        if FromStdin:
            inp=LI()
            org_inp.append(inp)
        else:
            inp=ls[i]
        if len(inp)==2:
            a,b=inp;c=1
        else:
            a,b,c=inp
        if index==1:a-=1;b-=1
        aa=(a,c);bb=(b,c);g[a].append(bb)
        if not Directed:g[b].append(aa)
    return g,org_inp
def GGI(h,w,search=None,replacement_of_found='.',mp_def={'#':1,'.':0},boundary=1):
    #h,w,g,sg=GGI(h,w,search=['S','G'],replacement_of_found='.',mp_def={'#':1,'.':0},boundary=1) # sample usage
    mp=[boundary]*(w+2);found={}
    for i in R(h):
        s=input()
        for char in search:
            if char in s:
                found[char]=((i+1)*(w+2)+s.index(char)+1)
                mp_def[char]=mp_def[replacement_of_found]
        mp+=[boundary]+[mp_def[j] for j in s]+[boundary]
    mp+=[boundary]*(w+2)
    return h+2,w+2,mp,found
def TI(n):return GI(n,n-1)
def accum(ls):
    rt=[0]
    for i in ls:rt+=[rt[-1]+i]
    return rt
def bit_combination(n,base=2):
    rt=[]
    for tb in R(base**n):s=[tb//(base**bt)%base for bt in R(n)];rt+=[s]
    return rt
def gcd(x,y):
    if y==0:return x
    if x%y==0:return y
    while x%y!=0:x,y=y,x%y
    return y
def YN(x):print(['NO','YES'][x])
def Yn(x):print(['No','Yes'][x])
def show(*inp,end='\n'):
    if show_flg:print(*inp,end=end)

mo=10**9+7
inf=float('inf')
FourNb=[(-1,0),(1,0),(0,1),(0,-1)];EightNb=[(-1,0),(1,0),(0,1),(0,-1),(1,1),(-1,-1),(1,-1),(-1,1)];compas=dict(zip('WENS',FourNb));cursol=dict(zip('LRUD',FourNb))
l_alp=string.ascii_lowercase
#sys.setrecursionlimit(10**7)
read=sys.stdin.buffer.read;readline=sys.stdin.buffer.readline;input=lambda:sys.stdin.readline().rstrip()

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

class Comb:
    def __init__(self,n,mo=10**9+7):
        self.fac=[0]*(n+1)
        self.inv=[1]*(n+1)
        self.fac[0]=1
        self.fact(n)
        for i in range(1,n+1):
            self.fac[i]=i*self.fac[i-1]%mo
            self.inv[n]*=i
            self.inv[n]%=mo
        self.inv[n]=pow(self.inv[n],mo-2,mo)
        for i in range(1,n):
            self.inv[n-i]=self.inv[n-i+1]*(n-i+1)%mo
        return
    
    def fact(self,n):
        return self.fac[n]
        
    def invf(self,n):
        return self.inv[n]

    def comb(self,x,y):
        if y<0 or y>x:
            return 0
        return self.fac[x]*self.inv[x-y]*self.inv[y]%mo


show_flg=False
show_flg=True

ans=0


a,b,c,d=LI()

cm=Comb(a+b+c+d+10)

def f(r,c):
    rt=0
    for i in range(r+1):
        rt+=cm.comb(i+c+1,c)
        rt%=mo
    return rt

print((f(c,d)-f(a-1,d)-f(c,b-1)+f(a-1,b-1))%mo)

Submission status: Accepted

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

mod = 10**9+7
MAX_N = 3*10**6

fact = [1]
fact_inv = [0]*(MAX_N+4)
for i in range(MAX_N+3):
    fact.append(fact[-1]*(i+1)%mod)

fact_inv[-1] = pow(fact[-1],mod-2,mod)
for i in range(MAX_N+2,-1,-1):
    fact_inv[i] = fact_inv[i+1]*(i+1)%mod

def comb(n,k,mod):
    if n<k:return 0
    return fact[n] * fact_inv[k] % mod * fact_inv[n-k] %mod

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

print(ans)

Submission status: Accepted

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

mod = 10**9+7
MAX_N = 3*10**6

fact = [1]
fact_inv = [0]*(MAX_N+4)
for i in range(MAX_N+3):
    fact.append(fact[-1]*(i+1)%mod)

fact_inv[-1] = pow(fact[-1],mod-2,mod)
for i in range(MAX_N+2,-1,-1):
    fact_inv[i] = fact_inv[i+1]*(i+1)%mod

def comb(n,k,mod):
    if n<k:return 0
    return fact[n] * fact_inv[k] % mod * fact_inv[n-k] %mod

ans=0
ans+=comb(c1+r1,r1,mod)
ans%=mod
ans-=comb(c1+r2+1,r2+1,mod)
ans%=mod
ans-=comb(c2+r1+1,r1,mod)
ans%=mod
ans+=comb(c2+r2+2,r2+1,mod)
ans%=mod

print(ans)

Submission status: Accepted

Solution code:


class Combination:
    def __init__(self, n_max, mod=10 ** 9 + 7):
        # O(n_max + log(mod))
        self.mod = mod
        f = 1
        self.fac = fac = [f]
        for i in range(1, n_max + 1):
            f = f * i % mod
            fac.append(f)
        f = pow(f, mod - 2, mod)
        self.facinv = facinv = [f]
        for i in range(n_max, 0, -1):
            f = f * i % mod
            facinv.append(f)
        facinv.reverse()

    # "n 要素" は区別できる n 要素
    # "k グループ" はちょうど k グループ

    def __call__(self, n, r):  # self.C と同じ
        return self.fac[n] * self.facinv[r] % self.mod * self.facinv[n - r] % self.mod

    def nCr(self, n, r):
        if not 0 <= r <= n:
            return 0
        return self.fac[n] * self.facinv[r] % self.mod * self.facinv[n - r] % self.mod

def resolve():
    def f(r, c):
        return cmb.nCr(r+c+2, r+1) - 1

    MOD = 10**9+7
    r1,c1,r2,c2 = map(int, input().split())
    r1 -= 1
    c1 -= 1

    cmb = Combination(r2+c2+5)
    ans = f(r2, c2)
    ans -= f(r1, c2)
    ans -= f(r2, c1)
    ans += f(r1, c1)
    print(ans % MOD)


if __name__ == "__main__":
    resolve()

Submission status: Accepted

Solution code:
MOD = 10**9 + 7
MOD_t_MAX = 2 * 10**6 + 10

fac  = [None] * MOD_t_MAX
finv = [None] * MOD_t_MAX
inv  = [None] * MOD_t_MAX
def MOD_COM_init():
    fac[0] = fac[1] = 1
    finv[0] = finv[1] = 1
    inv[1] = 1
    for i in range(2, MOD_t_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 MOD_COM(n, k):
    if n < k:
        return 0
    if n < 0 or k < 0:
        return 0
    return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD

def main():
    r1, c1, r2, c2 = map(int, input().split())
    MOD_COM_init()
    a = MOD_COM(r2+1+c2+1, r2+1) - 1
    b = MOD_COM(r2+1+c1, c1) - 1
    c = MOD_COM(r1+c2+1, r1) - 1
    d = MOD_COM(r1+c1, c1) - 1
    ans = a - (b + c) + d
    print(ans % MOD)

if __name__ == "__main__":
    main()

Submission status: Accepted

Solution code:
r1,c1,r2,c2=map(int,input().split())
mod=10**9+7
def comb(n,k,mod):
  if n<k:
    return 0
  if n-k<k:
    k=n-k
  c=1
  for x in range(n-k+1,n+1):
    c=(c*x)%mod
  d=1
  for x in range(1,k+1):
    d=(d*x)%mod
  c=c*pow(d,mod-2,mod)
  return c%mod
def f(i,j):
  return comb(i+j,i,mod)
ans=f(r2+1,c2+1)-f(r2+1,c1)-f(r1,c2+1)+f(r1,c1)
ans%=mod
print(ans)

Submission status: Accepted

Solution code:
MOD = 10**9 + 7

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

def getComb(n, k, MOD):
    if n < k:
        return 0
    if n-k < k:
        k = n-k
    comb = 1
    for x in range(n-k+1, n+1):
        comb = (comb * x) % MOD
    d = 1
    for x in range(1, k+1):
        d = (d * x) % MOD
    comb *= pow(d, MOD-2, MOD)
    return comb % MOD

def f(i, j):
    return getComb(i+j, j, MOD)

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

print(ans)

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")

M = 10**9+7 # 出力の制限
N = 2*10**6+4 # 必要なテーブルサイズ

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

ans = 0
r1,c1,r2,c2 = map(int, input().split())
for c in range(c1, c2+1):
    ans += cmb(r2+c, r2, M) - cmb(r1-1+c, r1-1, M)
for r in range(r1, r2+1):
    ans += cmb(c2+r, c2, M) - cmb(c1-1+r, c1-1, M)
    
# for r in range(r1+1, r2+1):
#     val = cmb(r+c1, r, M)
#     ans += val * (c2-c1) * (r2-r+1)
#     ans += val
#     ans %= M
# ans += cmb(r1+c1, r1, M)
# for c in range(c1+1, c2+1):
#     val = cmb(r1+c, c, M)
#     ans += val * (r2-r1) * (c2-c+1)
#     ans += val
#     ans %= M
print(ans%M)

Submission status: Accepted

Solution code:
def comb(n, r, p):
    x, y = 1, 1
    for i in range(n, n - r, -1):
        x *= i
        y *= i + r - n
        x %= p
        y %= p
    return pow(y, p - 2, p) * x % p

r1, c1, r2, c2 = map(int, input().split())
mod = pow(10, 9) + 7
s1, s2 = c1 + r1, c1 + r2 + 1
t1, t2 = min(c1 + 1, r1 - 1), min(c1 + 1, r2)
comb1 = comb(s1, t1, mod)
comb2 = comb(s2, t2, mod)
u1, u2 = s1 - r1 + 1, s2 - r2
ans = comb2 - comb1
for i in range(1, c2 - c1 + 1):
    comb1 = comb1 * (s1 + i) * pow(u1 + i, mod - 2, mod)
    comb1 %= mod
    comb2 = comb2 * (s2 + i) * pow(u2 + i, mod - 2, mod)
    comb2 %= mod
    ans += comb2
    ans -= comb1
    ans %= mod
print(ans)

Submission status: Accepted

Solution code:
import sys

stdin = sys.stdin


def ni(): return int(ns())


def na(): return list(map(int, stdin.readline().split()))


def ns(): return stdin.readline().rstrip()  # ignore trailing spaces

# 大きい数用


def modPow(a, n, p):
    if n == 1:
        return a
    if n % 2 == 1:
        return (a * (modPow(a, n // 2, p) ** 2)) % p
    else:
        return (modPow(a, n // 2, p) ** 2) % p


def modInverse(a, p):
    # calculates the modular multiplicative of a mod m.
    # (assuming p is prime).
    return modPow(a, p - 2, p)


def modBinomial(n, k, p):
    # calculates C(n,k) mod p (assuming p is prime).

    numerator = 1  # n * (n-1) * ... * (n-k+1)
    for i in range(k):
        numerator = (numerator * (n - i)) % p

    denominator = 1  # k!
    for i in range(1, k + 1):
        denominator = (denominator * i) % p

    # numerator / denominator mod p.
    return (numerator * modInverse(denominator, p)) % p


r1, c1, r2, c2 = na()
mod = 10 ** 9 + 7
print((modBinomial(r2 + c2 + 2, r2 + 1, mod) + modBinomial(r1 + c1, r1, mod) -
       modBinomial(r1 + c2 + 1, r1, mod) - modBinomial(r2 + c1 + 1, c1, mod)) % mod)

Submission status: Accepted

Solution code:
r1,c1,r2,c2 = map(int, input().split())
def find_power(n,mod=10**9+7):
    powlist=[0]*(n+1)
    powlist[0]=1
    powlist[1]=1
    for i in range(2,n+1):
        powlist[i]=powlist[i-1]*i%(mod)
    return powlist

def find_inv_power(n,mod=10**9+7):
    powlist=find_power(n)
    check=powlist[-1]
    first=1
    uselist=[0]*(n+1)
    secondlist=[0]*30
    secondlist[0]=check
    secondlist[1]=check**2
    for i in range(28):
        secondlist[i+2]=(secondlist[i+1]**2)%(10**9+7)
    a=format(10**9+5,"b")
    for j in range(30):
        if a[29-j]=="1":
            first=(first*secondlist[j])%(10**9+7)
    uselist[n]=first
    for i in range(n,0,-1):
        uselist[i-1]=(uselist[i]*i)%(10**9+7)
    return uselist

mod = 10**9+7
NUM = (2*10**6)+100
p_lis=find_power(NUM,mod)
ip_lis=find_inv_power(NUM,mod)

def comb(n,r,mod=10**9+7):
    if n<r:
        return 0
    elif n>=r:
        return (p_lis[n]*ip_lis[r]*ip_lis[n-r])%(mod)
def g(x,y):
    return comb(x+y+2,y+1)-1

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