Problem p03016 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <deque>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#define popcount __builtin_popcount
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef __int128_t lll;
ll MOD;
ll powmod(ll a, lll k) {
  ll ap = a, ans = 1;
  while (k) {
    if (k & 1) {
      ans *= ap;
      ans %= MOD;
    }
    ap = ap * ap;
    ap %= MOD;
    k >>= 1;
  }
  return ans;
}
vector<vector<ll>> matrixmul(int l, int m, int n, vector<vector<ll>> a,
                             vector<vector<ll>> b) {
  vector<vector<ll>> c;
  for (int i = 0; i < l; i++) {
    vector<ll> v;
    for (int j = 0; j < n; j++) {
      ll x = 0;
      for (int k = 0; k < m; k++) {
        x += (a[i][k] * b[k][j]);
        x %= MOD;
      }
      v.push_back(x);
    }
    c.push_back(v);
  }
  return c;
}
vector<vector<ll>> matrixpow(int n, vector<vector<ll>> a, ll k) {
  vector<vector<ll>> ap = a, ans;
  for (int i = 0; i < n; i++) {
    vector<ll> v;
    for (int j = 0; j < n; j++) {
      if (i == j) {
        v.push_back(1);
      } else {
        v.push_back(0);
      }
    }
    ans.push_back(v);
  }
  while (k) {
    if (k & 1)
      ans = matrixmul(n, n, n, ap, ans);
    ap = matrixmul(n, n, n, ap, ap);
    k >>= 1;
  }
  return ans;
}
int main() {
  ll l, a, b;
  cin >> l >> a >> b >> MOD;
  ll p = 1;
  ll cnt[20] = {};
  ll s[20] = {};
  for (int i = 0; i < 18; i++) {
    ll x = (p - a + b - 1) / b, y = (10 * p - a + b - 1) / b;
    if (x >= l || 10 * p - a <= 0) {
      p *= 10;
      continue;
    }
    y = min(y, l);
    x = max(0ll, x);
    if (x == y) {
      p *= 10;
      continue;
    }
    cnt[i] = y - x;
    vector<vector<ll>> mat;
    vector<ll> v[3];
    v[0].resize(3);
    v[0][0] = 10 * p % MOD, v[0][1] = 1, v[0][2] = b % MOD;
    mat.push_back(v[0]);
    v[1].resize(3);
    v[1][0] = 0, v[1][1] = 1, v[1][2] = b % MOD;
    mat.push_back(v[1]);
    v[2].resize(3);
    v[2][1] = 0, v[2][2] = 1, v[2][0] = 0;
    mat.push_back(v[2]);
    vector<vector<ll>> mp = matrixpow(3, mat, y - x - 1);
    ll a1 = a + x * b;
    s[i] = (mp[0][0] * (a1 % MOD) + mp[0][1] * (a1 % MOD) + mp[0][2]) % MOD;
    p *= 10;
  }
  // for(int i=0; i<18; i++) cout<<cnt[i]<<endl;
  // cout<<cnt[0]<<" "<<cnt[1]<<" "<<s[0]<<" "<<s[1]<<endl;
  ll ans = 0;
  lll c = 0;
  for (int i = 17; i >= 0; i--) {
    ans += s[i] * powmod(10, c) % MOD;
    c += cnt[i] * (ll)(i + 1);
    ans %= MOD;
  }
  cout << ans << endl;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <deque>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#define popcount __builtin_popcount
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef __int128_t lll;
ll MOD;
ll powmod(ll a, lll k) {
  ll ap = a, ans = 1;
  while (k) {
    if (k & 1) {
      ans *= ap;
      ans %= MOD;
    }
    ap = ap * ap;
    ap %= MOD;
    k >>= 1;
  }
  return ans;
}
vector<vector<ll>> matrixmul(int l, int m, int n, vector<vector<ll>> a,
                             vector<vector<ll>> b) {
  vector<vector<ll>> c;
  for (int i = 0; i < l; i++) {
    vector<ll> v;
    for (int j = 0; j < n; j++) {
      ll x = 0;
      for (int k = 0; k < m; k++) {
        x += (a[i][k] * b[k][j]);
        x %= MOD;
      }
      v.push_back(x);
    }
    c.push_back(v);
  }
  return c;
}
vector<vector<ll>> matrixpow(int n, vector<vector<ll>> a, ll k) {
  vector<vector<ll>> ap = a, ans;
  for (int i = 0; i < n; i++) {
    vector<ll> v;
    for (int j = 0; j < n; j++) {
      if (i == j) {
        v.push_back(1);
      } else {
        v.push_back(0);
      }
    }
    ans.push_back(v);
  }
  while (k) {
    if (k & 1)
      ans = matrixmul(n, n, n, ap, ans);
    ap = matrixmul(n, n, n, ap, ap);
    k >>= 1;
  }
  return ans;
}
int main() {
  ll l, a, b;
  cin >> l >> a >> b >> MOD;
  ll p = 1;
  ll cnt[20] = {};
  ll s[20] = {};
  for (int i = 0; i < 18; i++) {
    ll x = (p - a + b - 1) / b, y = (10 * p - a + b - 1) / b;
    if (x >= l || 10 * p - a <= 0) {
      p *= 10;
      continue;
    }
    y = min(y, l);
    x = max(0ll, x);
    if (x == y) {
      p *= 10;
      continue;
    }
    cnt[i] = y - x;
    vector<vector<ll>> mat;
    vector<ll> v[3];
    v[0].resize(3);
    v[0][0] = 10 * p % MOD, v[0][1] = 1, v[0][2] = b % MOD;
    mat.push_back(v[0]);
    v[1].resize(3);
    v[1][0] = 0, v[1][1] = 1, v[1][2] = b % MOD;
    mat.push_back(v[1]);
    v[2].resize(3);
    v[2][1] = 0, v[2][2] = 1, v[2][0] = 0;
    mat.push_back(v[2]);
    vector<vector<ll>> mp = matrixpow(3, mat, y - x - 1);
    ll a1 = a + x * b;
    s[i] = (mp[0][0] * (a1 % MOD) + mp[0][1] * (a1 % MOD) + mp[0][2]) % MOD;
    p *= 10;
  }
  // for(int i=0; i<18; i++) cout<<cnt[i]<<endl;
  // cout<<cnt[0]<<" "<<cnt[1]<<" "<<s[0]<<" "<<s[1]<<endl;
  ll ans = 0;
  lll c = 0;
  for (int i = 17; i >= 0; i--) {
    ans += s[i] * powmod(10, c) % MOD;
    c += (lll)cnt[i] * (lll)(i + 1);
    ans %= MOD;
  }
  cout << ans << endl;
  return 0;
}