题意:公式如下
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 .
题解:构造矩阵,第一列放a0到a9,然后第二列第一行放1,第三列第二行放1…第10列第9行放1,为了计算第n个数字并保留前9个数字。
#include <stdio.h>
#include <string.h>
const int N = 15;
struct Matrix {
int g[N][N];
}Ori, res;
int m, k;
void init() {
int a;
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
Ori.g[i][j] = res.g[i][j] = 0;
for (int i = 0; i < 10; i++) {
scanf("%d", &res.g[i][0]);
res.g[i][i + 1] = 1;
Ori.g[0][i] = 9 - i;
}
}
Matrix multiply(Matrix x, Matrix y) {
Matrix temp;
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
temp.g[i][j] = 0;
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
for (int l = 0; l < 10; l++)
temp.g[i][j] = (temp.g[i][j] + x.g[i][l] * y.g[l][j]) % m;
return temp;
}
void calc(int n) {
while (n) {
if (n & 1)
Ori = multiply(Ori, res);
n >>= 1;
res = multiply(res, res);
}
printf("%d\n", Ori.g[0][0]);
}
int main() {
while (scanf("%d%d", &k, &m) == 2) {
init();
if (k < 10) {
printf("%d\n", k % m);
continue;
}
k -= 9;
calc(k);
}
return 0;
}