题解
由题意可列矩阵
A=
⎛⎝⎜1110k011001⎞⎠⎟
F(n-1)= ⎛⎝⎜1i−1f[n−1]⎞⎠⎟
F(n)=A * F(n-1)
所以就可以用矩阵快速幂了,但是这题要注意分块快速幂。
代码
#include<cstdio>
#include<cstring>
using namespace std;
#define rep(i,x,y) for(int i = x;i <= y;i++)
#define dep(i,x,y) for(int i = x;i >= y;i--)
#define fill(a,x) memset(a,0,sizeof(a))
typedef long long LL;
LL n,mod,p[20];
struct matrix{
LL f[4][4];
}A,ans;
matrix mul(matrix a,matrix b)
{
matrix s;
fill(s.f,0);
rep(i,1,3) rep(j,1,3) rep(k,1,3)
s.f[i][j] = (s.f[i][j] + (a.f[i][k] * b.f[k][j]) % mod) % mod;
return s;
}
matrix pows(matrix e,LL b)
{
matrix s,a;
a = e;
rep(i,1,3) rep(j,1,3) if(i == j) s.f[i][j] = 1; else s.f[i][j] = 0;
while(b)
{
if(b & 1) s = mul(s,a);
a = mul(a,a);
b = b >> 1;
}
return s;
}
int main()
{
int maxk;
scanf("%lld%lld",&n,&mod);
p[0] = 1;
for(int i = 1;i <= 18;i++)
{
p[i] = p[i-1] * 10;
if(n < p[i] && n >= p[i-1]) maxk = i;
}
if(mod == 1){printf("0\n");return 0;}
fill(ans.f,0);
rep(i,1,3) ans.f[i][i] = 1;
int k = 1;
matrix e;
while(k < maxk)
{
fill(A.f,0);
rep(i,1,3) rep(j,1,i) A.f[i][j] = 1;
A.f[3][3] = p[k] % mod;
e = pows(A,p[k] - p[k-1]);
ans = mul(e,ans);
k ++;
}
fill(A.f,0);
rep(i,1,3) rep(j,1,i) A.f[i][j] = 1;
A.f[3][3] = p[k] % mod;
e = pows(A,n - p[k-1] + 1);
ans = mul(e,ans);
printf("%lld\n",ans.f[3][1]);
return 0;
}