Binomial Coefficient (Prime Mod)¶
- Title:
Binomial Coefficient (Prime Mod) - Judge / source:
Library Checker - Original URL: https://judge.yosupo.jp/problem/binomial_coefficient_prime_mod
- Secondary topics:
Lucas theorem,Binomial coefficients,Prime modulus - Difficulty:
medium - Subtype:
Choose between factorial-table binomial and Lucas digit decomposition under one prime modulus - Status:
solved - Solution file: binomialcoefficientprimemod.cpp
Why Practice This¶
This is the cleanest in-repo anchor for the Lucas theorem / large binomial mod prime lane because it does not let you blur together two different routes.
Under one prime modulus p, there are really two cases:
- if every query satisfies
n < p, one ordinary factorial table is enough - if some query crosses
n >= p, Lucas becomes the exact route
So the lesson here is not just "write Lucas."
It is:
- recognize the boundary
- choose the lighter route when it is enough
- fall back to digit decomposition only when needed
Recognition Cue¶
Reach for Lucas-safe thinking when:
- the statement asks for many values of
C(n, k) mod p - the modulus
pis prime - some
nmay be large enough that one factorial table no longer covers the query range
The strongest smell is:
- "same prime modulus for all queries, but
ncan crossp"
That is exactly when ordinary precompute stops being the whole story.
Problem-Specific Transformation¶
Each query asks for:
Because p is prime, the digit route is available:
where n_i, k_i are the base-p digits.
So the implementation split is:
- read all queries first
- if every
n < p, answer with one ordinary factorial table up tomax_n - otherwise, if
pis still precompute-safe, build0..p-1and answer with Lucas
That split is the real reusable pattern.
Core Idea¶
Use one prime-mod binomial helper in the easy regime and one Lucas wrapper in the large-n regime.
For Lucas:
- precompute
fact[i]andinv_fact[i]for0 <= i < p - for each query, repeatedly take:
ni = n % pki = k % p- multiply by
C(ni, ki) - if any digit has
ki > ni, return0 - divide
nandkbypand continue
The invariant is:
the current product already accounts for every processed base-p digit pair
Complexity¶
Two possible branches:
- ordinary factorial table:
- build
O(max_n) - query
O(1) - Lucas route:
- build
O(p) - query
O(log_p n)
That is exactly why the route chooser matters.
Pitfalls / Judge Notes¶
- Do not force Lucas if
max_n < p; that is just extra code and memory. - Do not force the ordinary factorial table if queries cross
n >= p. - Lucas only applies because the modulus is prime.
- A digit with
ki > nimakes the whole answer0. - The Lucas starter assumes
pis small enough for one0..p-1table.
Reusable Pattern¶
- Topic page: Lucas Theorem / Large Binomial Mod Prime
- Practice ladder: Lucas Theorem / Large Binomial Mod Prime ladder
- Starter template: lucas-binomial.cpp
- Notebook refresher: Lucas Theorem hot sheet
- Compare points:
- Distributing Apples
- Modular Arithmetic hot sheet
- This note adds: the route chooser between ordinary prime-mod binomial precompute and Lucas digit decomposition.