Language: C++

#include <algorithm>
#include <cfloat>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <string.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#define rep(i,n) for(int i=0;i<n;i++)
#define REP(i,n) for(int i=1;i<=n;i++)
#define int long long
#define ll long long
#define eps LDBL_EPSILON
#define mod 1000000007
#define double long double
#define INF LLONG_MAX/1000
#define P pair<int,int>
#define prique priority_queue
using namespace std;
class matrix {
	int n;
	vector<vector<int>> vec;
	void letMeasure() {
		rep(i, n) {
			rep(j, n) {
				if (i != j)vec[i][j] = 0;
				else vec[i][j] = 1;
			}
		}
	}
	void letZero() {
		rep(i, n) {
			rep(j, n)vec[i][j] = 0;
		}
	}
public:
	matrix(int n) {
		this->n = n;
		vec.resize(n, vector<int>(n));
	}
	matrix(int n, vector<int> vec) {
		if (vec.size() != n * n) {
			cerr << "Invalid construct in matrix" << endl;
			exit(1);
		}
		this->n = n;
		this->vec.resize(n, vector<int>(n));
		rep(i, n) {
			rep(j, n)this->vec[i][j] = vec[i * n + j];
		}
	}
	int operator[](int a) {
		return vec[a / n][a % n];
	}
	unsigned int size() {return n;}
	matrix operator*(const matrix a) {
		if (this->n != a.n) {
			cerr << "Invalid maltiple in matrix" << endl;
			exit(1);
		}
		vector<int> memo(n);
		rep(i, n) {
			rep(j, n) {
				rep(k, n) {
					memo[j] += vec[i][k] * a.vec[k][j] % m;
				}
			}
			vec[i] = memo;
			memo.clear();
			memo.resize(n);
		}
		return *this;
	}
	matrix letmod(int m) {
		rep(i, n) {
			rep(j, n)vec[i][j] %= m;
		}
		return *this;
	}
	static matrix measure(int n) {
		matrix res(n);
		res.letMeasure();
		return res;
	}
};
matrix mypow(matrix a, int b, int m) {
	a.letmod(m);
	if (!b)return matrix::measure(a.size());
	if (b % 2)return (mypow(a, b - 1, m) * a).letmod(m);
	matrix memo = mypow(a, b / 2, m);
	return (memo * memo).letmod(m);
}
int mypow(int a, int b) {
	if (!b)return 1;
	if (b % 2)return mypow(a, b - 1)* a;
	int memo = mypow(a, b / 2);
	return memo * memo;
}
int l, a, b, m;
signed main() {
	cin >> l >> a >> b >> m;
	int c = a + b * (l - 1);
	int ans[3] = { 0,a % m,1 };
	for (int i = 1; i <= 18; i++) {
		if (mypow(10, i) <= a)continue;
		int cnt;
		if (mypow(10, i) >= c) {
			if (mypow(10, i - 1) >= a)cnt = (c - a + b) / b - (mypow(10, i - 1) - 1 - a + b) / b;
			else cnt = (c - a + b) / b;
		}
		else {
			if (mypow(10, i - 1) >= a)cnt = (mypow(10, i) - 1 - a + b) / b - (mypow(10, i - 1) - 1 - a + b) / b;
			else cnt = (mypow(10, i) - 1 - a + b) / b;
		}
		if (cnt < 0)break;
		vector<int> vec{ mypow(10,i) % m,0,0,1,1,0,0,b % m,1 };
		matrix mat(3, vec);
		mat = mypow(mat, cnt, m);
		int memo[3] = { ans[0],ans[1],ans[2] };
		ans[0] = (memo[0] * mat[0] % m + memo[1] * mat[3] % m + memo[2] * mat[6] % m) % m;
		ans[1] = (memo[0] * mat[1] % m + memo[1] * mat[4] % m + memo[2] * mat[7] % m) % m;
		ans[2] = (memo[0] * mat[2] % m + memo[1] * mat[5] % m + memo[2] * mat[8] % m) % m;
	}
	cout << ans[0] << endl;
}

Compiler output:
a.cc: In member function 'matrix matrix::operator*(matrix)':
a.cc:76:78: error: 'm' was not declared in this scope; did you mean 'tm'?
   76 |                                         memo[j] += vec[i][k] * a.vec[k][j] % m;
      |                                                                              ^
      |                                                                              tm