Problem p02804 (python)

Fixed submission:
# encoding:utf-8
import copy
import random
import bisect #bisect_left　これで二部探索の大小検索が行える
import fractions #最小公倍数などはこっち
import math
import sys
import bisect
import collections

mod = 10**9+7
sys.setrecursionlimit(mod) # 再帰回数上限はでdefault1000
def LI(): return list(map(int, sys.stdin.readline().split()))

P = 10**9 + 7
N = 10000

n_ = 10**5 + 3

fun = [1 for i in range(n_+1)]
for i in range(1, n_ + 1):
    fun[i] = fun[i-1] * i % mod

rev = [1 for i in range(n_+1)]
rev[n_] = pow(fun[n_], mod-2, mod)
for i in range(n_-1,0,-1):
    rev[i] = rev[i+1]*(i+1) % mod

def nCr(n,r):
    if n <= 0 or r < 0 or r> n:return 0
    return fun[n]*rev[r]%mod*rev[n-r]%mod

N, K = LI()
A = LI()

A.sort()
B = copy.deepcopy(A)
B.reverse()
ans = 0

# max
tmp_n = N
tmp_k = K - 1
for b in B:
    tmp_n -= 1
    if tmp_n < tmp_k:
        break
    ans = (ans + b * nCr(tmp_n, tmp_k))%mod

# print(ans, "max")
# min
tmp_n = N
tmp_k = K - 1
for a in A:
    tmp_n -= 1
    if tmp_n < tmp_k:
        break
    ans = (ans - a * nCr(tmp_n, tmp_k))%mod

print(ans)

Buggy submission (verdict: Runtime Error):
# encoding:utf-8
import copy
import random
import bisect #bisect_left　これで二部探索の大小検索が行える
import fractions #最小公倍数などはこっち
import math
import sys
import bisect
import collections

mod = 10**9+7
sys.setrecursionlimit(mod) # 再帰回数上限はでdefault1000

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

N, K = LI()
A = LI()

A.sort()
B = copy.deepcopy(A)
B.reverse()
ans = 0

def ncr(n,r):
    return math.factorial(n) // (math.factorial(n - r) * math.factorial(r))

counts = collections.Counter(B)
# max
maxs = 0
tmp_n = N
for k, v in sorted(counts.items(), key=lambda x: -x[0]):
    tmp_n -= v
    for c in range(1,min(v, K) + 1):
        tmp_k = K - c
        if tmp_k <= 0 or tmp_n <= 0:
            pass
        else:
            ans += k * ncr(v, c) * ncr(tmp_n, tmp_k)
            ans = ans % mod

print(ans, "max")
# min
tmp_n = N
for k, v in sorted(counts.items()):
    tmp_n -= v
    for c in range(1,min(v, K) + 1):
        tmp_k = K - c
        if tmp_k <= 0 or tmp_n <= 0:
            pass
        else:
            ans -= k * ncr(v, c) * ncr(tmp_n, tmp_k)
            ans = ans % mod

print(ans % mod)

Buggy submission (verdict: Runtime Error):
# encoding:utf-8
import copy
import random
import bisect #bisect_left　これで二部探索の大小検索が行える
import fractions #最小公倍数などはこっち
import math
import sys
import bisect
import collections

mod = 10**9+7
sys.setrecursionlimit(mod) # 再帰回数上限はでdefault1000

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

N, K = LI()
A = LI()

A.sort()
B = copy.deepcopy(A)
B.reverse()
ans = 0

def ncr(n,r):
    return math.factorial(n) // (math.factorial(n - r) * math.factorial(r))

counts = collections.Counter(B)
# max
maxs = 0
tmp_n = N
for k, v in sorted(counts.items(), key=lambda x: -x[0]):
    tmp_n -= v
    for c in range(1,min(v, K) + 1):
        tmp_k = K - c
        if tmp_k <= 0 or tmp_n <= 0:
            pass
        else:
            ans += k * ncr(v, c) * ncr(tmp_n, tmp_k)

print(ans, "max")
# min
tmp_n = N
for k, v in sorted(counts.items()):
    tmp_n -= v
    for c in range(1,min(v, K) + 1):
        tmp_k = K - c
        if tmp_k <= 0 or tmp_n <= 0:
            pass
        else:
            ans -= k * ncr(v, c) * ncr(tmp_n, tmp_k)

print(ans % mod)