F[1] = a, F[2] = b, F[i] = 2 * F[i-2] + F[i-1] + i ^ 4, (i >= 3)
现在要求F[N]
类似于斐波那契数列的递推式子吧, 但是N最大能到int的最大值, 直接循环推解不了
所以就得用矩阵快速幂咯
现在就看转移矩阵长什么样了
Mi表示要求的矩阵 转移矩阵用A表示
A * Mi = Mi+1
矩阵Mi里面至少得有 F[i-1] F[i-2] i ^ 4 Mi+1就相应的有 F[i] F[i-1] (i+1)^4
(i+1)^4 = i^4 + 4 * i ^ 3 + 6 * i ^ 2 + 4 * i + 1
所以Mi中还得有i^3 i^2 i 1
总共就有七个元素
$\begin{pmatrix} 1 & 2 & 1 & 0 & 0 & 0 & 0 \\ 1 & 0& 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 1 & 4 & 6 & 4 & 1 \\ 0 & 0 & 0 & 1 & 3 & 3 & 1 \\ 0 & 0 & 0 & 0 & 1 & 2 & 1 \\ 0 & 0 & 0 & 0 & 0 & 1 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 1\end{pmatrix}
\times \begin{pmatrix} f_{i-1} \\ f_{i-2} \\ i^{4} \\ i^{3} \\ i^{2} \\ i \\ 1 \end{pmatrix} = \begin{pmatrix} f_{i} \\ f_{i-1} \\ (i+1)^{4} \\ (i+1)^{3} \\ (i+1)^{2} \\ i+1 \\ 1 \end{pmatrix}$
基本的矩阵运算,就是前面这个相当于系数的矩阵得是 (n-2)次幂 因为f1 f2都求过了
初始的矩阵是
$\begin{pmatrix} f_{2} \\ f_{1} \\ 3^{4} \\ 3^{3} \\ 3^{2} \\ 3 \\ 1 \end{pmatrix}$
也就是
$\begin{pmatrix} b \\ a \\ 81 \\ 27 \\ 9 \\ 3 \\ 1 \end{pmatrix}$
特判一下n == 1 和 2的情况就好啦
代码如下
#include <cstdio> #define ll long long #define MOD 2147493647 using namespace std; struct Matrix { ll m[7][7]; Matrix() { for (int i = 0; i < 7; i++) for (int j = 0; j < 7; j++) m[i][j] = 0; } }; Matrix mul(Matrix A, Matrix B) { Matrix temp; for (int i = 0; i < 7; i++) for (int j = 0; j < 7; j++) for (int k = 0; k < 7; k++) temp.m[i][j] = (temp.m[i][j] % MOD+ A.m[i][k] * B.m[k][j] % MOD) % MOD; return temp; } Matrix quick_mod(Matrix A, ll b) { Matrix ans; for (int i = 0; i < 7; i++) ans.m[i][i] = 1; while (b) { if (b & 1) ans = mul(ans, A); A = mul(A, A); b >>= 1; } return ans; } int main() { int T; scanf("%d", &T); while (T--) { int n, a, b; scanf("%d%d%d", &n, &a, &b); if (n == 1) printf("%d\n", a); else if (n == 2) printf("%d\n", b); else { Matrix ans; ans.m[0][0] = 1, ans.m[0][1] = 2, ans.m[0][2] = 1; ans.m[1][0] = 1; ans.m[2][2] = 1, ans.m[2][3] = 4, ans.m[2][4] = 6, ans.m[2][5] = 4, ans.m[2][6] = 1; ans.m[3][3] = 1, ans.m[3][4] = 3, ans.m[3][5] = 3, ans.m[3][6] = 1; ans.m[4][4] = 1, ans.m[4][5] = 2, ans.m[4][6] = 1; ans.m[5][5] = 1, ans.m[5][6] = 1, ans.m[6][6] = 1; ans = quick_mod(ans, (ll)n - 2); Matrix temp; temp.m[0][0] = b, temp.m[1][0] = a, temp.m[2][0] = 81, temp.m[3][0] = 27; temp.m[4][0] = 9, temp.m[5][0] = 3, temp.m[6][0] = 1; ans = mul(ans, temp); printf("%lld\n", ans.m[0][0] % MOD); } } return 0; }
其实可以封装一下Matrix 重载一下 * 和 ^ 运算符 这样就很方便也很好看啦
原文地址:https://www.cnblogs.com/Mrzdtz220/p/10433459.html