hdu 1757 A Simple Math Problem 矩阵乘法解线性方程

来源:互联网 发布:电子琴知乎 编辑:程序博客网 时间:2024/04/28 06:56
题目链接: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


代码如下:



#include<iostream>#include<cstdio>#include<math.h>#define maxn 100using 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;}