Time Complexity: O(logb)\mathcal O(\log b)

We will use digit DP to solve this problem.

Firstly, instead of finding the answer for the range [a,b][a, b], find the answers for the ranges [0,a1][0, a - 1] and [0,b][0, b] instead, and their difference will be the answer. (You'll find that one uses this technique for almost all digit DP problems).

Let dp[i][j]dp[i][j] be the number of good integers with ii digits and the ii-th digits is jj. The recurrence is dp[i][j]=k=09dp[i1][k]dp[i1][j]dp[i][j] = \sum_{k = 0}^9 dp[i - 1][k] - dp[i - 1][j] and the base cases are dp[1][j]=1dp[1][j] = 1 for each jj. Computing DP by hand will show you that dp[i][j]=9i1dp[i][j] = 9^{i - 1}.

How do we count the number of good integers not greater than some given xx with dd digits though? We have two cases:

  • The good integer has d<dd' < d digits.
  • The good integer has d=dd' = d digits.

Any good integer falling under the first case will be counted in the answer, so this case contributes exactly i=0d29i\sum_{i = 0}^{d - 2}9^i to the answer.

The second case is a bit trickier though. The key observation is that any good yy not greater than xx falling under this case satisfies two conditions:

  • xx and yy share a common prefix of length 0id0 \leq i \leq d without any equal neighbouring digits.
  • The (i+1)(i + 1)-th digit of yy is less than the (i+1)(i + 1)-th digits of xx.

This means that for each fixed (good) prefix of xx's digits, we can count the number of good yy with that prefix! If the ii-th digits of xx is sis_i, then it contributes si9dis_i \cdot 9^{d - i} to the answer. If si>si1s_i > s_{i - 1} though, then we must also subtract 9di9^{d - i} from the answer to prevent two consecutive digits from being equal.

Since we can process each digit of aa and bb in O(1)\mathcal O(1) time, this solution works in O(logb)\mathcal O(\log b) time.

C++

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
ll pow_9[19]{1};
ll calc(ll x) {
if (x == -1) return 0;
ll ans = 0;
vector<int> digits;

Join the USACO Forum!

Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!