This documentation is automatically generated by online-judge-tools/verification-helper
#include <cassert>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <vector>
// modを可変にする
#define MUTABLE
#include "../../math/modint.hpp"
#include "../../math/matrix.hpp"
using namespace std;
typedef long long ll;
using matrix = Matrix<ModInt>;
int main() {
ll l, a, b, m;
cin >> l >> a >> b >> m;
mod = m;
// ld[i]に、i桁の要素数を格納する
vector<ll> ld0(19), ld(19);
for (int i = 0; i <= 18; ++i) {
ll x = pow(10, i);
if (x <= a) continue;
ll d = (x-a+b-1)/b;
if (d > l) ld0[i] = l;
else ld0[i] = d;
ld[i] = ld0[i];
if (i > 0) ld[i] -= ld0[i-1];
}
matrix q(3);
q[0][0] = 1; q[1][1] = 1; q[2][2] = 1;
for (int i = 1; i <= 18; ++i) {
matrix p(3);
p[0][0] = pow(10, i); p[0][1] = 0; p[0][2] = 0;
p[1][0] = 1; p[1][1] = 1; p[2][2] = 0;
p[2][0] = 0; p[2][1] = b; p[2][2] = 1;
p ^= ld[i];
q *= p;
}
ModInt ans = q[1][0]*ModInt(a)+q[2][0];
cout << ans.val << endl;
}
#line 1 "test/atcoder/abc129-f.cpp"
#include <cassert>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <vector>
// modを可変にする
#define MUTABLE
#line 1 "math/modint.hpp"
// @title mod int
#line 3 "math/modint.hpp"
using ll = long long;
#ifdef MUTABLE
int mod;
#else
template<int mod>
#endif
struct ModInt {
int val;
ModInt inv() const{
int tmp,a=val,b=mod,x=1,y=0;
while(b)tmp=a/b,a-=tmp*b,std::swap(a,b),x-=tmp*y,std::swap(x,y);
return ModInt(x);
}
ModInt():val(0){}
ModInt(ll x){if((val=x%mod)<0)val+=mod;}
ModInt pow(ll t){ModInt res=1,b=*this; while(t){if(t&1)res*=b;b*=b;t>>=1;}return res;}
ModInt& operator+=(const ModInt& x){if((val+=x.val)>=mod)val-=mod;return *this;}
ModInt& operator-=(const ModInt& x){if((val+=mod-x.val)>=mod)val-=mod; return *this;}
ModInt& operator*=(const ModInt& x){val=(ll)val*x.val%mod; return *this;}
ModInt& operator/=(const ModInt& x){return *this*=x.inv();}
bool operator==(const ModInt& x) const{return val==x.val;}
bool operator!=(const ModInt& x) const{return val!=x.val;}
bool operator<(const ModInt& x) const{return val<x.val;}
bool operator<=(const ModInt& x) const{return val<=x.val;}
bool operator>(const ModInt& x) const{return val>x.val;}
bool operator>=(const ModInt& x) const{return val>=x.val;}
ModInt operator+(const ModInt& x) const{return ModInt(*this)+=x;}
ModInt operator-(const ModInt& x) const{return ModInt(*this)-=x;}
ModInt operator*(const ModInt& x) const{return ModInt(*this)*=x;}
ModInt operator/(const ModInt& x) const{return ModInt(*this)/=x;}
friend std::ostream& operator<<(std::ostream& os, const ModInt& mi) { os << mi.val; return os; }
static int get_mod() { return mod; }
};
constexpr int MOD10 = 1000000007;
constexpr int MOD99 = 998244353;
#ifndef MUTABLE
using modint = ModInt<MOD10>;
using modint99 = ModInt<MOD99>;
#endif
#line 1 "math/matrix.hpp"
// @title 行列
// 使用例:https://atcoder.jp/contests/abc189/submissions/19676965
#line 6 "math/matrix.hpp"
template< class T >
struct Matrix {
int H, W;
std::vector< std::vector< T > > A;
Matrix() {}
Matrix(int n, int m) : H(n), W(m), A(H, std::vector< T >(W, 0)) {}
Matrix(int n) : H(n), W(n), A(H, std::vector< T >(W, 0)) {};
Matrix(const std::vector<std::vector<T>>& a) : A(a) {
H = (int)a.size();
assert(H > 0);
W = (int)a[0].size();
}
int height() const { return H; }
int width() const { return W; }
inline const std::vector< T > &operator[](int k) const { return (A.at(k)); }
inline std::vector< T > &operator[](int k) { return (A.at(k)); }
static Matrix I(int n) {
Matrix mat(n);
for(int i = 0; i < n; i++) mat[i][i] = 1;
return (mat);
}
Matrix &operator+=(const Matrix &B) {
assert(H == B.H && W == B.W);
for(int i = 0; i < H; i++)
for(int j = 0; j < W; j++)
(*this)[i][j] += B[i][j];
return (*this);
}
Matrix &operator-=(const Matrix &B) {
assert(H == B.H && W == B.W);
for(int i = 0; i < H; i++)
for(int j = 0; j < W; j++)
(*this)[i][j] -= B[i][j];
return (*this);
}
Matrix &operator*=(const Matrix &B) {
assert(W == B.H);
std::vector< std::vector< T > > C(H, std::vector< T >(B.W, 0));
for(int i = 0; i < H; i++)
for(int j = 0; j < B.W; j++)
for(int k = 0; k < W; k++)
C[i][j] += ((*this)[i][k] * B[k][j]);
A.swap(C);
return (*this);
}
Matrix &operator^=(long long k) {
Matrix B = Matrix::I(H);
while(k > 0) {
if(k & 1) B *= *this;
*this *= *this;
k >>= 1LL;
}
A.swap(B.A);
return (*this);
}
std::vector<T> operator*(const std::vector<T> &v) {
assert(W == (int)v.size());
std::vector<T> ret(H, 0);
for(int i = 0; i < H; i++)
for(int j = 0; j < W; j++)
ret[i] += ((*this)[i][j] * v[j]);
return ret;
}
Matrix operator+(const Matrix &B) const { return (Matrix(*this) += B); }
Matrix operator-(const Matrix &B) const { return (Matrix(*this) -= B); }
Matrix operator*(const Matrix &B) const { return (Matrix(*this) *= B); }
Matrix operator^(const long long k) const { return (Matrix(*this) ^= k); }
friend std::ostream &operator<<(std::ostream &os, Matrix &p) {
for(int i = 0; i < p.H; i++) {
for(int j = 0; j < p.W; j++) {
os << p[i][j] << (j + 1 == p.W ? "\n" : " ");
}
}
return (os);
}
};
#line 12 "test/atcoder/abc129-f.cpp"
using namespace std;
typedef long long ll;
using matrix = Matrix<ModInt>;
int main() {
ll l, a, b, m;
cin >> l >> a >> b >> m;
mod = m;
// ld[i]に、i桁の要素数を格納する
vector<ll> ld0(19), ld(19);
for (int i = 0; i <= 18; ++i) {
ll x = pow(10, i);
if (x <= a) continue;
ll d = (x-a+b-1)/b;
if (d > l) ld0[i] = l;
else ld0[i] = d;
ld[i] = ld0[i];
if (i > 0) ld[i] -= ld0[i-1];
}
matrix q(3);
q[0][0] = 1; q[1][1] = 1; q[2][2] = 1;
for (int i = 1; i <= 18; ++i) {
matrix p(3);
p[0][0] = pow(10, i); p[0][1] = 0; p[0][2] = 0;
p[1][0] = 1; p[1][1] = 1; p[2][2] = 0;
p[2][0] = 0; p[2][1] = b; p[2][2] = 1;
p ^= ld[i];
q *= p;
}
ModInt ans = q[1][0]*ModInt(a)+q[2][0];
cout << ans.val << endl;
}