题目大意:求1234567891011121314...n mod m 的值
设F(n)=1234567891011121314...n 那么显然有F(n)=F(n-1)*(floor(lgn)+1)+n
于是我们可以矩乘
将数字按照floor(lgn)+1分类
构造状态矩阵F(n) n+1 1 初值为0 1 1
1~9的转移矩阵为
10 0 0
1 1 0
0 1 1
10~99的转移矩阵为
100 0
1 1
0 1
以此类推
注意构造矩阵的时候要取模不然会挂
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef unsigned long long ll;
struct Matrix{
ll xx[4][4];
Matrix(int flag)
{
int i,j;
for(i=1;i<=3;i++)
for(j=1;j<=3;j++)
if(i==j) xx[i][j]=flag;
else xx[i][j]=0;
}
Matrix(bool,ll digit)
{
xx[1][1]=digit;
xx[2][1]=xx[2][2]=xx[3][2]=xx[3][3]=1;
xx[1][3]=xx[1][2]=xx[2][3]=xx[3][1]=0;
}
ll* operator [] (int x)
{
return xx[x];
}
}ans(1);
ll n,p;
void operator *= (Matrix &x,Matrix y)
{
int i,j,k;
Matrix z(0);
for(i=1;i<=3;i++)
for(j=1;j<=3;j++)
for(k=1;k<=3;k++)
z[i][j]+=x[i][k]*y[k][j],z[i][j]%=p;
x=z;
}
Matrix Quick_Power(Matrix x,ll y)
{
Matrix re(1);
while(y)
{
if(y&1) re*=x;
x*=x;y>>=1;
}
return re;
}
int main()
{
ll i;
cin>>n>>p;
for(i=10;i<=n;i*=10)
ans*=Quick_Power(Matrix(true,i%p),i-i/10);
ans*=Quick_Power(Matrix(true,i%p),n-i/10+1);
cout<<(ans[2][1]+ans[3][1])%p<<endl;
}