Overview
Instead of iterating all numbers in `[L, R]`, we construct numbers digit by digit. To solve for `[L, R]`, we typically compute `solve(R) - solve(L-1)`.
Loading...
Loading Curriculum...
Loading Subject...
Loading Topic...
Loading Lesson...
Loading Lab...
Count the number of integers in a range `[L, R]` that satisfy a certain property using digit-by-digit construction.
Instead of iterating all numbers in `[L, R]`, we construct numbers digit by digit. To solve for `[L, R]`, we typically compute `solve(R) - solve(L-1)`.
A boolean variable `tight` tracks if the digits chosen so far match the prefix of `R`. If true, the next digit cannot exceed the next digit of `R`.
Once `tight` becomes false (we picked a smaller digit), the choices for remaining digits are entirely unconstrained and can be heavily reused (memoized).
The state usually looks like `dp[idx][tight][other_constraints]`. The number of states is extremely small relative to the value of `R` (logarithmic).