Problem p03016 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

#ifdef DEBUG
#include "../include/debug.hpp"
#else
#define debug(...) 42
#define rdfile(...) 42
#endif

typedef vector<long long> vec;
typedef vector<vector<long long>> mat;

const long long INF = LLONG_MAX;
long long L, A, B, M;

long long pow10(long long n, long long M) {
  if (n == 0)
    return 1;
  if (n % 2 == 0) {
    long long t = pow10(n / 2, M);
    return (t * t) % M;
  }
  return (10 * pow10(n - 1, M)) % M;
}

mat mult(mat A, mat B) {
  mat ret(A.size(), vec(B[0].size(), 0));
  for (int i = 0; i < A.size(); ++i) {
    for (int j = 0; j < B[0].size(); ++j) {
      for (int k = 0; k < A[0].size(); ++k) {
        ret[i][j] += A[i][k] * B[k][j];
        ret[i][j] %= M;
      }
    }
  }
  return ret;
}

mat pow(mat A, long long n) {
  if (n == 0) {
    return {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
  }
  if (n % 2 == 0) {
    mat t = pow(A, n / 2);
    return mult(t, t);
  }
  return mult(A, pow(A, n - 1));
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  // rdfile("_input.txt");

  cin >> L >> A >> B >> M;

  long long ans = 0;

  for (long long d = 1; d <= 18; ++d) { // d:=桁数
    long long l = pow10(d - 1, INF) - A;
    l = (l % B && l > 0) ? l / B + 1 : l / B;
    l = max(l, 0LL);

    long long r = pow10(d, INF) - A;
    r = (r % B && r > 0) ? r / B + 1 : r / B;
    r = min(r, L);

    if (l >= r)
      continue;
    ans = (ans * pow10((r - l) * d, M)) % M;

    long long si, ai;
    si = ((A % M) + (B % M) * (l % M)) % M;
    ai = si;

    mat m = {{pow10(d, M), 0, 0}, {1, 1, 0}, {B % M, B % M, 1}};
    m = pow(m, r - l - 1);

    ans += (ai * m[0][0]) % M + (si * m[1][0]) % M + m[2][0];
    ans %= M;
  }

  cout << ans << endl;

  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

#ifdef DEBUG
#include "../include/debug.hpp"
#else
#define debug(...) 42
#define rdfile(...) 42
#endif

typedef vector<long long> vec;
typedef vector<vector<long long>> mat;

const long long INF = LLONG_MAX;
long long L, A, B, M;

long long pow10(long long n, long long M) {
  if (n == 0)
    return 1;
  if (n % 2 == 0) {
    long long t = pow10(n / 2, M);
    return (t * t) % M;
  }
  return (10 * pow10(n - 1, M)) % M;
}

mat mult(mat A, mat B) {
  mat ret(A.size(), vec(B[0].size(), 0));
  for (int i = 0; i < A.size(); ++i) {
    for (int j = 0; j < B[0].size(); ++j) {
      for (int k = 0; k < A[0].size(); ++k) {
        ret[i][j] += A[i][k] * B[k][j];
        ret[i][j] %= M;
      }
    }
  }
  return ret;
}

mat pow(mat A, long long n) {
  if (n == 0) {
    return {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
  }
  if (n % 2 == 0) {
    mat t = pow(A, n / 2);
    return mult(t, t);
  }
  return mult(A, pow(A, n - 1));
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  // rdfile("_input.txt");

  cin >> L >> A >> B >> M;

  long long ans = 0;

  for (long long d = 1; d <= 18; ++d) { // d:=桁数
    long long l = pow10(d - 1, INF) - A;
    l = (l % B && l > 0) ? l / B + 1 : l / B;
    l = max(l, 0LL);

    long long r = pow10(d, INF) - A;
    r = (r % B && r > 0) ? r / B + 1 : r / B;
    r = min(r, L);

    if (l >= r)
      continue;

    // ans = (ans * pow10((r-l)*d, M)) % M;
    for (int i = 0; i < d; ++i) {
      ans *= pow10(r - l, M);
      ans %= M;
    }

    long long si, ai;
    si = ((A % M) + (B % M) * (l % M)) % M;
    ai = si;

    mat m = {{pow10(d, M), 0, 0}, {1, 1, 0}, {B % M, B % M, 1}};
    m = pow(m, r - l - 1);

    ans += (ai * m[0][0]) % M + (si * m[1][0]) % M + m[2][0];
    ans %= M;
  }

  cout << ans << endl;

  return 0;
}