HDU 5950 Recursive sequence 矩阵快速幂
http://acm.hdu.edu.cn/showproblem.php?pid=5950
一开始以为i^4不能矩阵快速幂,但是结论是可以得,那么要怎么递推呢?
矩阵快速幂的思路都是一样的,matrix_a * matrix_b ^ n
其中,想要维护什么,就在matrix_a写,比如现在是F[n - 1], F[n - 2],我想要递推到下一项,那么就
会变成F[n], F[n - 1],这个时候,你就要寻找一下F[n]和F[n - 1]有什么关系。
i^4也一样,想要从i^4 递推到 (i + 1)^4,就要看看他们之间有什么关系。
那么把(i + 1)^4用二项式定理展开,就知道了。
关键要掌握矩阵快速幂的思路,都是从F[n]递推到F[n + 1],寻找一下它们之间的关系就好
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <assert.h> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> #include <bitset> const LL MOD = 2147493647; const int maxn = 8 + 2; struct Matrix { LL a[maxn][maxn]; int row, col; }; struct Matrix matrix_mul(struct Matrix a, struct Matrix b, LL MOD) { struct Matrix c = {0}; c.row = a.row; c.col = b.col; for (int i = 1; i <= a.row; ++i) { for (int k = 1; k <= a.col; ++k) { if (a.a[i][k]) { for (int j = 1; j <= b.col; ++j) { c.a[i][j] += a.a[i][k] * b.a[k][j]; c.a[i][j] = (c.a[i][j] + MOD) % MOD; } } } } return c; } struct Matrix quick_matrix_pow(struct Matrix ans, struct Matrix base, int n, LL MOD) { while (n) { if (n & 1) { ans = matrix_mul(ans, base, MOD); } n >>= 1; base = matrix_mul(base, base, MOD); } return ans; } void work() { int n, a, b; scanf("%d%d%d", &n, &a, &b); if (n == 1) { printf("%d\n", a); return; } if (n == 2) { printf("%d\n", b); return; } struct Matrix t1 = {0}; t1.row = 1, t1.col = 7; t1.a[1][1] = b, t1.a[1][2] = a, t1.a[1][3] = 81, t1.a[1][4] = 27, t1.a[1][5] = 9, t1.a[1][6] = 3, t1.a[1][7] = 1; struct Matrix t2 = {0}; t2.row = t2.col = 7; t2.a[1][1] = 1, t2.a[1][2] = 1; t2.a[2][1] = 2; t2.a[3][1] = 1, t2.a[3][3] = 1; t2.a[4][3] = 4, t2.a[4][4] = 1; t2.a[5][3] = 6, t2.a[5][4] = 3, t2.a[5][5] = 1; t2.a[6][3] = 4, t2.a[6][4] = 3, t2.a[6][5] = 2, t2.a[6][6] = 1; t2.a[7][3] = 1, t2.a[7][4] = 1, t2.a[7][5] = 1, t2.a[7][6] = 1, t2.a[7][7] = 1; struct Matrix ans = quick_matrix_pow(t1, t2, n - 2, MOD); printf("%I64d\n", ans.a[1][1]); } int main() { #ifdef local freopen("data.txt", "r", stdin); // freopen("data.txt", "w", stdout); #endif int t; scanf("%d", &t); while (t--) work(); return 0; }
既然选择了远方,就要风雨兼程~
posted on 2017-03-18 21:29 stupid_one 阅读(144) 评论(0) 编辑 收藏 举报