题目大意:求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 0
1 1 0
0 1 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; }
原文地址:http://blog.csdn.net/popoqqq/article/details/42009071