[数据结构与算法-10]矩阵加速
矩阵加速
思路
利用矩阵运算,将递推数列转化为矩阵之幂,利用矩阵快速幂加速数列的计算
P1939 【模板】矩阵加速(数列)
题目描述
已知一个数列 a,它满足:
\[a_x = \left\{ \begin{matrix} 1 & x\in\{1, 2, 3\}\\ a_{x-1} + a_{x-3} & x \geq 4 \end{matrix} \right. \]求 a 数列的第 n 项对 10^9+7 取余的值。
输入格式
第一行一个整数 T,表示询问个数。
以下 T 行,每行一个正整数 n。
输出格式
每行输出一个非负整数表示答案。
输入输出样例
输入 #1复制
3 6 8 10输出 #1复制
4 9 19说明/提示
- 对于 30% 的数据 n \(\leq\) 100 ;
- 对于 60% 的数据 n \(\leq2 \times 10^7\);
- 对于 100% 的数据 \(1 \leq T \leq 100,1 \leq n \leq 2 \times 10^9\)。
解答
构造向量
\[\left(\begin{matrix}
f[i]\\
f[i-1]\\
f[i-2]
\end{matrix}\right)
\]
寻找加速矩阵M
利用递推公式
\[\left(\begin{matrix}
f[i]   \\
f[i-1] \\
f[i-2] \\
\end{matrix}\right)=
\left(\begin{matrix}
f[i-1] \times 1 + f[i-2] \times 0 + f[i-3] \times 1\\
f[i-1] \times 1 + f[i-2] \times 0 + f[i-3] \times 0\\
f[i-1] \times 0 + f[i-2] \times 1 + f[i-3] \times 0\\
\end{matrix}\right)=
\left(\begin{matrix}
1 & 0 & 1 \\
1 & 0 & 0 \\
0 & 1 & 0 \\ 
\end{matrix}\right) \times
\left(\begin{matrix}
f[i-1]   \\
f[i-2] \\
f[i-3] \\
\end{matrix}\right)
\]
求出通项
\[\left(\begin{matrix}
f[i]   \\
f[i-1] \\
f[i-2] \\
\end{matrix}\right)=
\left(\begin{matrix}
1 & 0 & 1 \\
1 & 0 & 0 \\
0 & 1 & 0 \\ 
\end{matrix}\right)^{i - 1} \times
\left(\begin{matrix}
f[1] \\
f[2] \\
f[3] \\
\end{matrix}\right)
\]
利用矩阵快速幂求解
#include <cstdio>
#include <cstring>
#define MOD 1000000007
int T, N;
struct Matrix {
	long long e[4][4];
}M,E;
// 重载运算符
Matrix operator*(const Matrix& a, const Matrix& b) {
	Matrix ans;
	memset(ans.e, 0, sizeof(ans.e));
	for (int i = 1; i <= 3; i++)
		for (int j = 1; j <= 3; j++)
			for (int k = 1; k <= 3; k++) {
				ans.e[i][j] += a.e[i][k] * b.e[k][j] % MOD;
				ans.e[i][j] %= MOD;
			}
	return ans;
}
int main() {
	scanf("%d", &T);
	for (int i = 0; i < T; i++) {
		scanf("%d", &N);
        // 初始化
		memset(E.e, 0, sizeof(E.e));
		memset(M.e, 0, sizeof(M.e));
		for (int i = 1; i <= 3; i++)
			E.e[i][i] = 1;
		M.e[1][1] = M.e[1][3] = M.e[2][1] = M.e[3][2] = 1;
        // 快速幂
		while (N) {
			if (N & 1)E = E * M;
			M = M * M;
			N >>= 1;
		}
		printf("%d\n", E.e[2][1]);
	}
	return 0;
}

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号