题目链接:http: //acm.hdu.edu.cn/showproblem.php?pid=1757
题意:
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);
给出 一个k, m;
求f(k)%m.
对于第二个样例而言,构造如下的矩阵:
20 500
1 0 1 0 1 0 1 0 1 0
1 0 1 0 1 0 1 0 1 0 (系数在第一行)
1 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 1 0
题意:
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);
给出 一个k, m;
求f(k)%m.
对于第二个样例而言,构造如下的矩阵:
20 500
1 0 1 0 1 0 1 0 1 0
1 0 1 0 1 0 1 0 1 0 (系数在第一行)
1 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 1 0
代码如下:
#include<iostream>
#include<cstdio>
#include<math.h>
#define maxn 100
using namespace std;
int x, mod;
struct Matrix {
int n, m;
int mat[maxn][maxn];
Matrix() {
n = m = maxn;
memset(mat, 0, sizeof(mat));
}
inline void init(int aa, int bb) {
n = aa;
m = bb;
}
inline void init_e(int aa, int bb) {
int i, j;
n = aa;
m = bb;
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
mat[i][j] = (i == j);
}
};
Matrix mul(Matrix a, Matrix b) //矩阵乘法
{
Matrix ret;
ret.init(a.n, b.m);
int i, j, k;
for (i = 0; i < a.n; i++) {
for (j = 0; j < b.m; j++)
if (a.mat[i][j]) {
for (k = 0; k < b.m; k++)
if (b.mat[j][k]) {
ret.mat[i][k] += a.mat[i][j] * b.mat[j][k];
if (ret.mat[i][k] >= mod)
ret.mat[i][k] %= mod;
}
}
}
return ret;
}
Matrix mi(Matrix a, int b) //矩阵幂
{
Matrix ret, temp = a;
ret.init_e(a.n, a.m);
while (b) {
if (b & 1)
ret = mul(ret, temp);
temp = mul(temp, temp);
b >>= 1;
}
return ret;
}
void pri(Matrix b) {
int i, j;
for (i = 0; i < b.n; i++) {
for (j = 0; j < b.m; j++)
printf("- ", b.mat[i][j]);
printf("\n");
}
}
int main() {
int i;
Matrix init, s, ans;
init.init(10, 10);
for (i = 0; i < 10 - 1; i++)
init.mat[i + 1][i] = 1;
while (scanf("%d%d", &x, &mod) != EOF) {
ans.init(10, 10);
int a[10];
Matrix now = init;
for (i = 0; i < 10; i++)
scanf("%d", &now.mat[0][i]);
if (x < 10) {
printf("%d\n", x % mod);
continue;
}
// pri(now);
ans = mi(now, x - 9); //
int res = 0;
for (i = 0; i < 10; i++)
res += ans.mat[0][i] * (9 - i);
printf("%d\n", res % mod);
}
return 0;
}