목차

이항 계수 (Binomial Coefficient)

관련 정리

정확한 값을 계산

파스칼의 삼각형

이항계수를 큰 소수로 나눈 나머지를 구할 때

값을 한번만 계산할 때

코드

teflib.combinatorics.comb

관련 문제

값을 여러번 계산해야 할 때

코드

teflib.combinatorics.CombTable

관련 문제

특수한 경우들 - 모듈러스 M이 n보다 큰 소수가 아닌 경우

분자와 분모를 모두 소인수분해해서 계산하는 방법

코드

for p in numtheory.prime_list(N):
        prime_pow = p
        e = 0
        while prime_pow <= N:
            e += (N // prime_pow) - (K // prime_pow) - ((N - K) // prime_pow)
            prime_pow *= p
        ans = ans * pow(p, e, M) % M

관련 문제

모듈러스가 n보다 작은 소수일 때

코드

from teflib import combinatorics

comb_table = combinatorics.CombTable(M - 1, M)
answer = 1
while N > 0:
    N, n_mod = divmod(N, M)
    K, k_mod = divmod(K, M)
    answer *= comb_table.get(n_mod, k_mod)
answer %= M

관련 문제

모듈러스 M이 p^e 형태일때

코드

fact, inv = precompute_for_prime_pow(p, e):
def comb_mod_prime_pow(n, k, p, e):
    """Returns C(n, k) % (p^e)."""
    mod = p**e
    r = n - k
    answer = 1
    t = 0
    while n > 0:
        answer *= fact[n % mod] * inv[k % mod] * inv[r % mod]
        if (n // mod + k // mod + r // mod) % 2 == 1:
            answer *= -1
        n //= p
        k //= p
        r //= p
        t += n - k - r
    return answer * pow(p, t) % mod

모듈러스가 임의의 합성수일 때

코드

def precompute(MOD_FACTORS):
    facts = {}
    invs = {}
    for p, e in MOD_FACTORS.items():
        mod = p**e
        facts[mod], invs[mod] = precompute_for_prime_pow(p, e)
    return facts, invs

def comb_mod_m(N, K, MOD_FACTORS):
    rems = []
    mods = []
    for p, e in MOD_FACTORS.items():
        mod = p**e    
        rems.append(comb_mod_prime_pow(N, K, p, e, facts[mod], invs[mod]))
        mods.append(mod)
        print(numtheory.linear_congruences(rems, mods))

관련 문제