标签:
题目链接:戳我
一个函数 f(x) 当 x < 10 ,f(x) = x;
当 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的值
略
用矩阵快速幂,建立A 矩阵为 10 * 10的,如下
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
a[9] a[8] a[7] a[6] a[5] a[4] a[3] a[2] a[1] a[0] 其中a数组为上面公式所对应的a
B矩阵为 10 * 1 的, 如下
[0;1;2;3;4;5;6;7;8;9]
故f(n) 为 An * B 所得矩阵的最后一个元素
//Author LJH //www.cnblogs.com/tenlee #include <cstdio> #include <cstdlib> #include <cstring> #include <cctype> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <map> #define clc(a, b) memset(a, b, sizeof(a)) using namespace std; const int inf = 0x3f; const int INF = 0x3f3f3f3f; const int maxn = 10; int k, m; void Init(int a[][maxn], int ans[][maxn]) { for(int i = 0; i < 9; i++) { for(int j = 0; j < 10; j++) { a[i][j] = 0; if(j-1 == i) { a[i][j] = 1; } } } for(int i = 0; i < maxn; i++) { for(int j = 0; j < maxn; j++) { if(i == j) ans[i][j] = 1; else ans[i][j] = 0; } } } void matrix_mul(int a[][maxn], int b[][maxn]) { int i, j, k; int tmp[maxn][maxn] = {0}; for(i = 0; i < maxn; i++) { for(j = 0; j < maxn; j++) { for(k = 0; k < maxn; k++) { tmp[i][j] = (tmp[i][j] + a[i][k] * b[k][j] % m) % m; } } } for(i = 0; i < maxn; i++) { for(j = 0; j < maxn; j++) { a[i][j] = tmp[i][j]; } } /*for(int i = 0; i < maxn; i++) { for(int j = 0; j < maxn; j++) printf("b %d ", a[i][j]); puts(""); }*/ } int quickPow(int a[maxn][maxn], int b[maxn], int ans[maxn][maxn], int n) { /*for(int i = 0; i < maxn; i++) { for(int j = 0; j < maxn; j++) printf("%d ", a[i][j]); puts(""); }*/ while(n) { if(n & 1) matrix_mul(ans, a); matrix_mul(a, a); n >>= 1; } /*for(int i = 0; i < maxn; i++) { for(int j = 0; j < maxn; j++) printf("%d ", ans[i][j]); puts(""); }*/ int sum = 0; for(int i = 0; i < maxn; i++) { sum = (sum + i * ans[9][i]) % m; } return sum % m; } void func(int a[][maxn]) { int d[50]; for(int i = 0; i < 10; i++) d[i] = i; for(int i = 10; i <= k; i++) { d[i] = 0; for(int j = 0; j < 10; j++) { d[i] = (d[i] + a[9][j] * d[i-j-1] % m) % m; } printf("%d#%d ", i, d[i]); } puts(""); } int main() { freopen("1.txt", "r", stdin); int a[maxn][maxn], b[maxn], ans[maxn][maxn]; while(~scanf("%d %d\n", &k, &m)) { Init(a, ans); for(int i = 0; i < 10; i++) { scanf("%d", &a[9][9-i]); } //func(a); if(k >= 10) printf("%d\n", quickPow(a, b, ans, k-9)); else printf("%d\n", k%m); } return 0; }
HDU 1757 A Simple Math Problem(矩阵快速幂)
标签:
原文地址:http://www.cnblogs.com/tenlee/p/4662438.html