【模板】矩阵乘法

矩阵乘法基础模板:

P3390 【模板】矩阵快速幂

在矩阵快速幂中,正对角线为\(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;
}

P1939 【模板】矩阵加速(数列)

构造矩阵得

\[\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;
}

P1962 斐波那契数列

构造矩阵得

\[\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().

posted @ 2019-09-18 21:22  Paranoid丶离殇  阅读(329)  评论(1编辑  收藏  举报