题目:
If x < 10 f(x) = x.
If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);And ai(0<=i<=9) can only be 0 or 1 .
Now, I will give a0 ~ a9 and two positive integers k and m ,and could you help Lele to caculate f(k)%m.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
int nn=10; //实际矩阵边长
const int N=10; //乘矩阵边长最大值
int M;//要模的数
struct Matrix
{
int f[N][N];
void Init0()
{
memset(f,0,sizeof(f));
}
};
Matrix Matrix_mul(Matrix a,Matrix b)
{
int i,j,k;
Matrix ans;
ans.Init0();
for(i=0;i<nn;i++)
for(j=0;j<nn;j++)
for(k=0;k<nn;k++)
{
ans.f[i][j]+=a.f[i][k]*b.f[k][j];
ans.f[i][j]%=M;
}
return ans;
}
Matrix QuickPow(Matrix a,int n)
{
int i,j,k;
Matrix ans,mul;
mul=a;
ans.Init0();
for(i=0;i<nn;i++) ans.f[i][i]=1;
while(n)
{
if(n&1) ans=Matrix_mul(ans,mul);
mul=Matrix_mul(mul,mul);
n>>=1;
}
return ans;
}
int cal(int x)
{
Matrix a;
int i,j,n,ans;
if(x<10) return x%M;
a.Init0();
for(i=0;i<10;i++)
scanf("%d",&a.f[i][0]);
for(i=1;i<10;i++)
a.f[i-1][i]=1;
a=QuickPow(a,x-9);
ans=0;
for(i=0;i<10;i++) ans=(ans+(9-i)*a.f[i][0])%M;
return ans;
}
int main()
{
int n;
while(scanf("%d%d",&n,&M)!=EOF)
printf("%d\n",cal(n));
return 0;
}