古典叙事 · 技术札记

序章

山河有卷
人间有声

写代码,也写长风、旧城与未熄的灯。
愿每一篇随笔,都有自己的山水与回声。
阅览随笔

矩阵快速幂板子

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

const int N = 105; // 通常矩阵大小不超过 100
const i64 MOD = 1e9 + 7;

i64 n, m;

// 1. 将矩阵封装进结构体,完美解决传参、返回值和赋值问题!
struct Matrix {
    i64 mat[N][N];
    
    // 构造函数:创建矩阵时自动清零
    Matrix() {
        memset(mat, 0, sizeof(mat));
    }
};

// 2. 矩阵乘法
Matrix multi(const Matrix& a, const Matrix& b) {
    Matrix res;
    // 小常数优化:将 k 放到第二层循环,利用 CPU 缓存,速度快 3 倍左右
    for (int i = 1; i <= n; i++) {
        for (int k = 1; k <= n; k++) {
            i64 r = a.mat[i][k]; 
            if (r == 0) continue; // 剪枝优化
            
            for (int j = 1; j <= n; j++) {
                res.mat[i][j] = (res.mat[i][j] + r * b.mat[k][j]) % MOD;
            }
        }
    }
    return res;
}

// 3. 矩阵快速幂 (注意:b 是指数,是一个 i64 整数!)
Matrix ksm(Matrix a, i64 b) {
    Matrix res;
    // 初始化 res 为单位矩阵 (对角线为 1,其余为 0)
    // 单位矩阵在矩阵乘法中的地位,就等同于数字乘法中的 "1"
    for (int i = 1; i <= n; i++) {
        res.mat[i][i] = 1;
    }
    
    // 熟悉的快速幂逻辑,完全不用改!
    while (b > 0) {
        if (b & 1) res = multi(res, a);
        a = multi(a, a);
        b >>= 1;
    }
    return res;
}

void solve() {
    cin >> n >> m;
    Matrix base;
    
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            cin >> base.mat[i][j];
        }
    }
    
    // 代码瞬间变得像普通整数运算一样优雅
    Matrix ans = ksm(base, m);
    
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            cout << ans.mat[i][j] << " ";
        }
        cout << "\n";
    }
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    solve();
    return 0;
}
posted @ 2026-08-14 10:10  Morphis‘  阅读(5)  评论(0)    收藏  举报