Description
题解
[fnn1]=[fn−1n−11]×⎡⎣⎢10k11011001⎤⎦⎥
对于 0…9 , 10…99 , 100…999 ,…, 10t…n 分段计算。
#include<bits/stdc++.h>
using namespace std;
#define rep(i, l, r) for(int i = (l); i <= (r); i++)
typedef long long ll;
ll n, m;
struct Mat{
ll dat[5][5];
Mat(){memset(dat, 0, sizeof(dat));}
friend Mat operator * (const Mat a, const Mat b){
Mat mul;
rep(i, 1, 3) rep(j, 1, 3) rep(k, 1, 3)
mul.dat[i][j] = (mul.dat[i][j] + a.dat[i][k] * b.dat[k][j]) % m;
return mul;
}
friend Mat operator ^ (const Mat p, ll n){
Mat q = p, ret;
rep(i, 1, 3) ret.dat[i][i] = 1;
while(n){
if(n & 1) ret = ret * q;
q = q * q;
n >>= 1;
}
return ret;
}
}a;
void init(){
scanf("%lld%lld", &n, &m);
}
void cal(ll t, ll fin){
Mat b;
b.dat[1][1] = t % m;
b.dat[2][1] = b.dat[2][2] = b.dat[3][1] = b.dat[3][2] = b.dat[3][3] = 1;
b = b ^ (fin - t / 10 + 1);
a = a * b;
}
void work(){
ll t = 10;
a.dat[1][3] = 1;
while(t <= n){
cal(t, t-1);
t *= 10;
}
cal(t, n);
printf("%lld\n", a.dat[1][1]);
}
int main(){
init();
work();
return 0;
}