题目链接:HDU - 1757
题意:定义了一个函数:f(x);
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);
递推式已经有了,再找转移矩阵f(0)~f(9)分别是0, 1, 2, 3, 4, 5, 6, 7, 8, 9;
10*10的矩阵;
#include
using namespace std;
const int M=15;
long long k, m;
long long a[M];
long long t[M][M], f[]={9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
void mul(long long x[][M], long long y[][M]){
long long temp[15][15];
memset(temp, 0, sizeof(temp));
for(int i=0; i<10; i++){
for(int j=0; j<10; j++){
for(int k=0; k<10; k++){
temp[i][j]=(temp[i][j]+x[i][k]*y[k][j]%m)%m;
}
}
}
for(int i=0; i<10; i++){
for(int j=0; j<10; j++){
x[i][j]=temp[i][j];
}
}
return;
}
long long Power(long long x[][15], long long n){
long long temp[15][15];
for(int i=0; i<10; i++){
for(int j=0; j<10; j++){
temp[i][j]=(i==j?1:0);
}
}
while(n){
if(n&1) mul(temp, x);
mul(x, x);
n>>=1;
}
long long ans=0;
for(int i=0; i<10; i++){
ans=(ans+temp[0][i]*f[i]%m)%m;
}
return ans;
}
int main(){
while(~scanf("%lld%lld", &k, &m)){
memset(t, 0, sizeof(t));
for(int i=0; i<10; i++){
scanf("%lld", &a[i]);
t[0][i]=a[i];
}
for(int i=1; i<10; i++){
t[i][i-1]=1;
}
if(k<10) printf("%lld\n", k%m);
else{
printf("%lld\n", Power(t, k-9));
}
}
return 0;
}