1. 程式人生 > >HDU 5950 Recursive sequence(矩陣構造+矩陣快速冪)

HDU 5950 Recursive sequence(矩陣構造+矩陣快速冪)

題目地址
題意:就說告訴你f(1) = a,f(2) = b,f(n) = f(n−1)+2∗f(n−2)+n^4,求出f(n)的值。
思路:這類題目就是用矩陣快速冪來寫的,這類題目難的就是構造矩陣,我們可以發現一些規律(如下)

f(n) = f(n−1)+2∗f(n−2)+n^4
(n+1)^4=n^4+4*n^3+6*n^2+4*n+1
(n+1)^3=n^3+3*n^2+3*n+1
(n+1)^2=n^2+2*n+1
n+1=n+1
1=1

然後我們就可以構造出一個矩陣為:這裡寫圖片描述然後就用矩陣快速冪就好了。

#include <iostream>
#include <cstring> #include <string> #include <queue> #include <vector> #include <map> #include <set> #include <stack> #include <cmath> #include <cstdio> #include <algorithm> #define LL long long #define N 1100 #define M 50010 #define inf 0x3f3f3f3f
using namespace std; const LL mod = 2147493647; const double eps = 1e-9; struct node { int n, m; LL jz[7][7]; }sum, a; node mul(node x, node y) { node num; num.n = x.n; num.m = y.m; for (int i = 0; i < x.n; i++) { for (int j = 0; j < y.m; j++) { num.jz
[i][j] = 0; for (int k = 0; k < x.m; k++) { num.jz[i][j] += x.jz[i][k] * y.jz[k][j]; num.jz[i][j] %= mod; } } } return num; } node pow(node x, node y, LL m) { while (m) { if (m & 1) { x = mul(x, y); } m /= 2; y = mul(y, y); } return x; } void init(int aa, int bb) { a.n = 7; a.m = 7; a.jz[0][0] = 1, a.jz[0][1] = 1, a.jz[0][2] = 0, a.jz[0][3] = 0, a.jz[0][4] = 0, a.jz[0][5] = 0, a.jz[0][6] = 0; a.jz[1][0] = 2, a.jz[1][1] = 0, a.jz[1][2] = 0, a.jz[1][3] = 0, a.jz[1][4] = 0, a.jz[1][5] = 0, a.jz[1][6] = 0; a.jz[2][0] = 1, a.jz[2][1] = 0, a.jz[2][2] = 1, a.jz[2][3] = 0, a.jz[2][4] = 0, a.jz[2][5] = 0, a.jz[2][6] = 0; a.jz[3][0] = 4, a.jz[3][1] = 0, a.jz[3][2] = 4, a.jz[3][3] = 1, a.jz[3][4] = 0, a.jz[3][5] = 0, a.jz[3][6] = 0; a.jz[4][0] = 6, a.jz[4][1] = 0, a.jz[4][2] = 6, a.jz[4][3] = 3, a.jz[4][4] = 1, a.jz[4][5] = 0, a.jz[4][6] = 0; a.jz[5][0] = 4, a.jz[5][1] = 0, a.jz[5][2] = 4, a.jz[5][3] = 3, a.jz[5][4] = 2, a.jz[5][5] = 1, a.jz[5][6] = 0; a.jz[6][0] = 1, a.jz[6][1] = 0, a.jz[6][2] = 1, a.jz[6][3] = 1, a.jz[6][4] = 1, a.jz[6][5] = 1, a.jz[6][6] = 1; sum.n = 1; sum.m = 7; sum.jz[0][0] = bb; sum.jz[0][1] = aa; sum.jz[0][2] = 16; sum.jz[0][3] = 8; sum.jz[0][4] = 4; sum.jz[0][5] = 2; sum.jz[0][6] = 1; } int main() { cin.sync_with_stdio(false); int T; LL aa, bb, n; cin >> T; while (T--) { cin >> n >> aa >> bb; if (n == 1) { cout << aa << endl; continue; } if (n == 2) { cout << bb << endl; continue; } init(aa, bb); sum = pow(sum, a, n - 2); cout << sum.jz[0][0] << endl; } return 0; }