矩阵快速幂主要用于求一个很复杂的递推式的某一项问题。当一个线性递推式直接暴力计算复杂度太高时,便可考虑用矩阵快速幂加速。
矩阵快速幂复杂度:log2n3 = 3log2n = O(logn)
Code:
typedef long long ll;
const int N = 2;
const ll mod = 1e9 + 7;
struct Matrix { //结构体,矩阵类型
ll m[N][N];
Matrix() {
memset(m,0,sizeof(m));
}
friend Matrix operator * (Matrix a, Matrix b) { //计算矩阵a*矩阵b
Matrix tmp; //定义一个临时矩阵保持矩阵a*矩阵b的结果
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
tmp.m[i][j] = 0;
for (int k = 0; k < N; k++) {
tmp.m[i][j] = (tmp.m[i][j] + a.m[i][k] * b.m[k][j]) % mod;
}
}
}
return tmp;
}
friend Matrix operator ^ (Matrix base, ll n) { //快速幂,计算矩阵 base的 n次方
Matrix ans; //对于求整数的幂是初始化为1,而求矩阵的幂需要初始化为一个单位矩阵E,A*E=A
for (int i = 0; i < N; i++)
ans.m[i][i] = 1;
while (n) {
if (n & 1) ans = ans * base; //*已重载,所以不能缩写成*=了
base = base * base;
n >>= 1;
}
return ans;
}
};
下图是一些递推式:
关于如何构造矩阵:
求数列第N项
an = ( 3an-1 + 4an-2 ) mod 1e9+7,输入三个正整数 n, a1, a2,输出 an
数据规模:1 ≤ n ≤ 1012,1 ≤ a1,a2 ≤ 10
时间限制:1秒
题解: 矩阵快速幂模板题,从数据规模的大小很明显可以看出单纯递推会超时。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2;
const ll mod = 1e9 + 7;
struct Matrix {
ll m[N][N];
Matrix() {
memset(m,0,sizeof(m));
}
friend Matrix operator * (Matrix a, Matrix b) {
Matrix tmp;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
tmp.m[i][j] = 0;
for (int k = 0; k < N; k++) {
tmp.m[i][j] = (tmp.m[i][j] + a.m[i][k] * b.m[k][j]) % mod;
}
}
}
return tmp;
}
friend Matrix operator ^ (Matrix base, ll n) {
Matrix ans;
for (int i = 0; i < N; i++)
ans.m[i][i] = 1;
while (n) {
if (n & 1) ans = ans * base;
base = base * base;
n >>= 1;
}
return ans;
}
};
int main()
{
ll n, a1, a2;
cin >> n >> a1 >> a2;
Matrix tem, res, ans;
tem.m[0][0] = a2, tem.m[1][0] = a1;
res.m[0][0] = 3, res.m[0][1] = 4, res.m[1][0] = 1, res.m[1][1] = 0;
if (n <= 2) {
if (n == 1) cout << a1 << endl;
else cout << a2 << endl;
return 0;
}
ans = (res ^ (n-2)) * tem;
cout << ans.m[0][0] % mod << endl;
return 0;
}