http://acm.hdu.edu.cn/showproblem.php?pid=1757
思路:矩阵快速幂 ,通过化简,得出下面公式:
所以主要的问题就是求出中间矩阵的n-9次方,设中间矩阵为A
那么A^n-9可以通过快速幂求出来,比如 A^10=A^(1010)=A^8*A^2(只需要计算5次)。
核心代码:
matrix matrix_quick_power(matrix a,int k)//矩阵快速幂0.0
{
matrix b;
memset(b.mat,0,sizeof(b.mat));
for(int i=0;i<10;i++) b.mat[i][i]=1;//单位矩阵b
while(k)
{
if(k%2==1) b=matrix_mul(a,b);
a=matrix_mul(a,a);
k/=2;
}
return b;
}
完整代码:
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
int n,mod;
struct matrix
{
int mat[10][10];
}A,B;
matrix matrix_mul(matrix a,matrix b)
{
matrix c;
memset(c.mat,0,sizeof(c.mat));
int i,j,k;
for(int i=0;i<10;i++)
for(int j=0;j<10;j++)
for(int k=0;k<10;k++)
c.mat[i][j]+=a.mat[i][k]*b.mat[k][j],c.mat[i][j]%=mod;
return c;
}
matrix matrix_quick_power(matrix a,int k)//矩阵快速幂0.0
{
matrix b;
memset(b.mat,0,sizeof(b.mat));
for(int i=0;i<10;i++) b.mat[i][i]=1;//单位矩阵b
while(k)
{
if(k%2==1) b=matrix_mul(a,b);
a=matrix_mul(a,a);
k/=2;
}
return b;
}
int main()
{
while(~scanf("%d%d",&n,&mod))
{
for(int i=0;i<10;i++) scanf("%d",&A.mat[0][i]);
for(int i=1;i<10;i++) A.mat[i][i-1]=1;
B=matrix_quick_power(A,n-9);
int sum=0;
for(int i=0;i<10;i++) sum+=B.mat[0][i]*(10-i-1),sum%=mod;
printf("%d\n",sum);
}
}