Problem p03016 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define db double
#define pii pair<int, int>
#define pli pair<ll, int>
#define pil pair<int, ll>
#define pll pair<ll, ll>
#define mat vector<vector<ll>>
const int inf = 1 << 30;
const ll linf = 1e18;
const db EPS = 1e-7;
template <class T> void chmin(T &x, T y) {
  if (x > y)
    x = y;
}
template <class T> void chmax(T &x, T y) {
  if (x < y)
    x = y;
}

ll L, A, B, M;

mat mat_mul(const mat &m1, const mat &m2) {
  mat res = {};
  for (int i = 0; i + 1 < m1.size(); ++i) {
    if (m1[i].size() != m1[i + 1].size())
      return res;
  }
  for (int i = 0; i + 1 < m2.size(); ++i) {
    if (m2[i].size() != m2[i + 1].size())
      return res;
  }
  if (m1[0].size() != m2.size())
    return res;

  int n = m1.size(), m = m2[0].size();

  res = mat(n, vector<ll>(m, 0));

  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      for (int k = 0; k < m1[0].size(); k++) {
        res[i][j] += m1[i][k] * m2[k][j];
        res[i][j] %= M;
      }
    }
  }
  return res;
}

mat dia_mat(int sz) {
  mat res = mat(sz, vector<ll>(sz, 0));
  for (int i = 0; i < sz; i++)
    res[i][i] = 1;
  return res;
}

mat mat_pow(mat m, ll exp) {
  mat res = dia_mat(m.size());
  while (exp > 0) {
    if (exp % 2) {
      res = mat_mul(res, m);
    }
    m = mat_mul(m, m);
    exp /= 2;
    res[0][0] %= M;
    m[0][0] %= M;
  }
  return res;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cin >> L >> A >> B >> M;

  int cnt = 0;
  mat m1 = {{0, A, 1}};
  ll d = 1;
  while (cnt < L) {
    auto culc = [](ll num) -> ll {
      if (num < A)
        return 0;
      else
        return ((num - A) / B) + 1;
    };

    ll cnt2 = culc(d * 10 - 1);
    cnt2 -= culc(d - 1);
    if (cnt + cnt2 > L)
      cnt2 = L - cnt;
    cnt += cnt2;
    d *= 10;
    mat m2 = {{d % M, 0, 0}, {1, 1, 0}, {0, B, 1}};
    mat m3 = mat_pow(m2, cnt2);
    m1 = mat_mul(m1, m3);
    m1[0][0] %= M;
  }
  cout << m1[0][0] << endl;
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define db double
#define pii pair<int, int>
#define pli pair<ll, int>
#define pil pair<int, ll>
#define pll pair<ll, ll>
#define mat vector<vector<ll>>
const int inf = 1 << 30;
const ll linf = 1e18;
const db EPS = 1e-7;
template <class T> void chmin(T &x, T y) {
  if (x > y)
    x = y;
}
template <class T> void chmax(T &x, T y) {
  if (x < y)
    x = y;
}

ll L, A, B, M;

mat mat_mul(const mat &m1, const mat &m2) {
  mat res = {};
  for (int i = 0; i + 1 < m1.size(); ++i) {
    if (m1[i].size() != m1[i + 1].size())
      return res;
  }
  for (int i = 0; i + 1 < m2.size(); ++i) {
    if (m2[i].size() != m2[i + 1].size())
      return res;
  }
  if (m1[0].size() != m2.size())
    return res;

  int n = m1.size(), m = m2[0].size();

  res = mat(n, vector<ll>(m, 0));

  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      for (int k = 0; k < m1[0].size(); k++) {
        res[i][j] += m1[i][k] * m2[k][j];
        res[i][j] %= M;
      }
    }
  }
  return res;
}

mat dia_mat(int sz) {
  mat res = mat(sz, vector<ll>(sz, 0));
  for (int i = 0; i < sz; i++)
    res[i][i] = 1;
  return res;
}

mat mat_pow(mat m, ll exp) {
  mat res = dia_mat(m.size());
  while (exp > 0) {
    if (exp % 2) {
      res = mat_mul(res, m);
    }
    m = mat_mul(m, m);
    exp /= 2;
    res[0][0] %= M;
    m[0][0] %= M;
  }
  return res;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cin >> L >> A >> B >> M;

  ll cnt = 0;
  mat m1 = {{0, A, 1}};
  ll d = 1;
  while (cnt < L) {
    auto culc = [](ll num) -> ll {
      if (num < A)
        return 0;
      else
        return ((num - A) / B) + 1;
    };

    ll cnt2 = culc(d * 10 - 1);
    cnt2 -= culc(d - 1);
    if (cnt + cnt2 > L)
      cnt2 = L - cnt;
    cnt += cnt2;
    d *= 10;
    mat m2 = {{d % M, 0, 0}, {1, 1, 0}, {0, B, 1}};
    mat m3 = mat_pow(m2, cnt2);
    m1 = mat_mul(m1, m3);
    m1[0][0] %= M;
  }
  cout << m1[0][0] << endl;
  return 0;
}