【模板】矩阵乘法
矩阵乘法基础模板:
在矩阵快速幂中,正对角线为\(1\),其他为\(0\)的矩阵为单位矩阵。
利用单位矩阵进行快速幂。
code:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const LL mod = 1e9 + 7;
LL n, k, flag;
struct Matrix {
LL a[105][105];
Matrix() { memset(a, 0, sizeof(a)); }
inline LL *operator [] (int x) { return a[x]; }
Matrix operator * (Matrix b) {
Matrix res;
for(int i = 1; i <= n; i ++) {
for(int k= 1; k <= n; k ++) {
for(int j = 1; j <= n; j ++) {
(res[i][j] += a[i][k] * b[k][j]) %= mod;
}
}
}
return res;
}
} a, base;
Matrix Matrix_ksm(Matrix x, LL y) {
Matrix res = base;
for( ; y ; x = x * x, y >>= 1) {
if(y & 1) res = res * x;
}
return res;
}
int main() {
cin >> n >> k;
for(int i = 1; i <= n; i ++) {
for(int j = 1; j <= n; j ++) {
cin >> a[i][j];
}
}
for(int i = 1; i <= n; i ++) base[i][i] = 1;
Matrix ans = Matrix_ksm(a, k);
for(int i = 1; i <= n;i ++) {
for(int j = 1; j <= n; j ++) {
cout << ans[i][j] << " ";
}
cout << endl;
}
return 0;
}
构造矩阵得
\[\left[\begin{matrix}a_{n+1}\\a_{n}\\a_{n-1} \end{matrix}\right] = \left[\begin{matrix}1&0&1\\1&0&0\\0&1&0 \end{matrix}\right] * \left[\begin{matrix}a_{n}\\a_{n-1}\\a_{n-2} \end{matrix}\right]
\]
套上矩阵快速幂即可
code:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const LL mod = 1e9 + 7;
LL t, n;
struct Matrix {
LL a[4][4];
Matrix() { memset(a, 0, sizeof(a)); }
inline LL *operator [] (int x) { return a[x]; }
Matrix operator * (Matrix b) {
Matrix res;
for(int i = 1; i <= 3; i ++) {
for(int k= 1; k <= 3; k ++) {
for(int j = 1; j <= 3; j ++) {
(res[i][j] += a[i][k] * b[k][j]) %= mod;
}
}
}
return res;
}
} ans, base;
void Matrix_ksm(LL y) {
for( ; y ; base = base * base, y >>= 1) {
if(y & 1) ans = ans * base;
}
}
void INIT() {
for(int i = 1; i <= 3; i ++) {
for(int j = 1; j <= 3; j ++) {
base[i][j] = 0;
ans[i][j] = 0;
}
}
base[1][1] = base[1][3] = base[2][1] = base[3][2] = 1;
ans[1][1] = ans[2][1] = ans[3][1] = 1;
}
int main() {
cin >> t;
while(t --> 0) {
cin >> n;
if(n <= 3) { puts("1"); continue; }
INIT();
Matrix_ksm(n-1);
cout << ans[1][1] << endl;
}
return 0;
}
构造矩阵得
\[\left[\begin{matrix}f_{n}\\f_{n-1}\end{matrix}\right] = \left[\begin{matrix}1&1\\1&0 \end{matrix}\right] * \left[\begin{matrix}f_{n-1}\\f_{n-2}\end{matrix}\right]
\]
同样套上矩阵快速幂即可
code:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const LL mod = 1e9 + 7;
LL n;
struct Matrix {
LL a[3][3];
Matrix() { memset(a, 0, sizeof(a)); }
inline LL *operator[] (int x) { return a[x]; }
Matrix operator * (Matrix b) {
Matrix res;
for(int i = 1; i <= 2; i ++) {
for(int k = 1; k <= 2; k ++) {
for(int j = 1; j <= 2; j ++) {
(res[i][j] += a[i][k] * b[k][j]) %= mod;
}
}
}
return res;
}
} ans, base;
void Matrix_ksm(LL y) {
for( ; y ; base = base * base, y >>= 1)
if(y & 1) ans = ans * base;
}
void INIT() {
base[1][1] = base[1][2] = base[2][1] = 1;
ans[1][1] = ans[1][2] = 1;
}
int main() {
cin >> n;
if(n <= 2) return puts("1"), 0;
INIT();
Matrix_ksm(n-2);
printf("%lld\n", ans[1][1]);
return 0;
}
一般构造矩阵的方法就是rand(), 使劲rand().
作者:Paranoid丶离殇
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。