洛谷 P3390 【模板】矩阵快速幂
思路
显然,这是一道矩阵快速幂模板题
矩阵快速幂是一个重要的东西,在许多题中可以找出转移矩阵,然后用矩阵快速幂加速,从而达到可以被接受的复杂度。
若两个矩阵可以相乘,当且仅当他们之中一个矩阵的行数等于另一个矩阵的列数,设\(A\)为 \(n\times k\) 矩阵,\(B\) 为 \(k \times m\) 矩阵,则他们的乘积 \(C\) 为 \(n\times m\) 矩阵,有公式 \(C_{i,j}=\sum\limits_{l=1}^k A_{i,l}\times B_{l, j}\)。
在这里还要注意要有一个单位矩阵,这个单位矩阵是干什么的呢?其实就是一个非 \(0\) 即 \(1\) 的正方形矩阵,左上角到右下角对角线上的数为 \(1\),其他地方都为 \(0\),一个矩阵与单位矩阵相乘,得到的结果还是这个矩阵,相当于一个数的乘 \(1\) 操作。
说完矩阵乘法和单位矩阵,就可以做这个题了,定义矩阵结构体,并重载矩阵相乘的 \(*\) 号运算符,就可以进行矩阵的快速幂操作,和普通快速幂差不多,原理也相似,不懂可以看代码,如果看不明白我写的,那么推荐这篇题解。
代码
/*
Name: P3390 【模板】矩阵快速幂
Author: Loceaner
Date:
Description:
Debug: 不要在结构体里开数组开的太大
矩阵记得初始化
*/
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define int long long
using namespace std;
const int A = 1e2 + 11;
const int B = 1e6 + 11;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
inline int read() {
char c = getchar();
int x = 0, f = 1;
for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
return x * f;
}
int n, k;
struct matrix {
int a[A][A];
matrix() { memset(a, 0, sizeof(a)); }
void init() { for (int i = 1; i <= n; i++) a[i][i] = 1; }
} a, ans;
matrix operator * (const matrix &x, const matrix &y) {
matrix ans;
for (int k = 1; k <= n; k++)
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
ans.a[i][j] = (ans.a[i][j] + x.a[i][k] * y.a[k][j] % mod) % mod;
return ans;
}
inline void power() {
while (k) {
if (k & 1) ans = ans * a;
a = a * a, k >>= 1;
}
}
signed main() {
n = read(), k = read();
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
a.a[i][j] = read();
ans.init();
power();
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++)
cout << ans.a[i][j] << " ";
puts("");
}
return 0;
}
转载不必联系作者,但请声明出处