Language: C++

#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>

using namespace std;

typedef long long ll;

#define fi first
#define se second
#define mp make_pair
#define pb push_back

#define range(i, a, b, s) for (ll i = (a), __##i = (b); i < __##i; i += (s))
#define down(i, a, b, s) for (ll i = (a), __##i = (b); __##i < i; i += (s))

ll l, a, b, mod = 1e7, c[20], d[20];

template <typename T>
using matrix = vector<vector<T>>;

template <typename T>
ostream& operator<<(ostream& cout, const vector<T>& rhs) {
  cout << "[";
  range(i, 0, rhs.size(), 1) {
    if (i != 0) cout << ", ";
    cout << rhs[i];
  }
  return cout << "]";
}

template <typename T>
matrix<T> diag(size_t n, T v = 1) {
  matrix<T> ans(n, vector<T>(n, 0));
  range(i, 0, n, 1) { ans[i][i] = v % mod; }
  return ans;
}

#define define_mat_mat_element_wise_ops(op)                              \
  template <typename T>                                                  \
  matrix<T> operator op(matrix<T> lhs, matrix<T> rhs) {                  \
    const size_t n1 = lhs.size();                                        \
    const size_t n2 = lhs[0].size();                                     \
    matrix<T> ans(n1, vector<T>(n2, 0));                                 \
    range(i, 0, n1, 1) {                                                 \
      range(j, 0, n2, 1) { ans[i][j] = (lhs[i][j] op rhs[i][j]) % mod; } \
    }                                                                    \
    return ans;                                                          \
  }

define_mat_mat_element_wise_ops(+);

template <typename T>
vector<T> dot(vector<T>& lhs, matrix<T>&& rhs) {
  const size_t n1 = rhs.size();
  const size_t n2 = rhs[0].size();
  vector<T> ans(n2, 0);
  range(i, 0, n1, 1) {
    range(j, 0, n2, 1) { ans[j] = (ans[j] + (lhs[i] * rhs[i][j] % mod)) % mod; }
  }
  return ans;
}

template <typename T>
matrix<T> dot(matrix<T>& lhs, matrix<T>& rhs) {
  const size_t n1 = lhs.size();
  const size_t n2 = lhs[0].size();
  const size_t n3 = rhs[0].size();
  matrix<T> ans(n1, vector<T>(n3, 0));
  range(i, 0, n1, 1) {
    range(j, 0, n2, 1) {
      range(k, 0, n3, 1) {
        ans[i][k] = (ans[i][k] + (lhs[i][j] * rhs[j][k] % mod)) % mod;
      }
    }
  }
  return ans;
}

template <typename X, typename N>
X pow(X x, N n) {
  if (n == 0) return 1;
  if (n == 1) return x;
  X y = pow(x, n / 2);
  X ans = y * y;
  if (n % 2 == 0)
    return ans;
  else
    return ans * x;
}

template <typename N>
matrix<ll> mat_pow(matrix<ll> x, N n) {
  if (n == 0) return diag<ll>(x.size(), 1);
  if (n == 1) return x;
  matrix<ll> y = mat_pow(x, n / 2);
  matrix<ll> ans = dot(y, y);
  if (n % 2 == 0)
    return ans;
  else
    return dot(ans, x);
}

int main(int argc, char const* argv[]) {
  // freopen("F.txt", "r", stdin);

  while (cin >> l >> a >> b >> mod) {
    memset(c, 0, sizeof(c));
    memset(d, 0, sizeof(d));

    ll weight = 9;
    range(i, 1, 19, 1) {
      if (weight >= b) {
        c[i] = (weight - a) / b + 1;
        bool flag = (c[i] > l);
        if (flag) {
          c[i] = l;
        }
        d[i] = (c[i] - c[i - 1]) % mod;
        if (flag) break;
      }
      weight = weight * 10 + 9;
    }
    vector<ll> ans = {0, a, 1};
    range(i, 1, 19, 1) {
      matrix<ll> rhs = {
          {pow<ll>(10, i) % mod, 0, 0},
          {1, 1, 0},
          {0, b % mod, 1},
      };
      ans = dot(ans, mat_pow(rhs, d[i]));
    }
    cout << ans[0] << endl;
  }
  return 0;
}

Compiler output:
a.cc: In function 'int main(int, const char**)':
a.cc:112:5: error: 'memset' was not declared in this scope
  112 |     memset(c, 0, sizeof(c));
      |     ^~~~~~
a.cc:6:1: note: 'memset' is defined in header '<cstring>'; this is probably fixable by adding '#include <cstring>'
    5 | #include <set>
  +++ |+#include <cstring>
    6 | #include <string>