矩阵快速幂

按照线性代数中的矩阵乘法规则,常见的矩阵乘法写法如下:

for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++)
        for (int k = 1; k <= n; k++)
            c[i][j] += a[i][k] * b[k][j]

但是我们强烈建议你调整循环的顺序,按照如下方式书写矩阵乘法:

for (int i = 1; i <= n; i++)
    for (int k = 1; k <= n; k++)
        for (int j = 1; j <= n; j++)
            c[i][j] += a[i][k] * b[k][j]

虽然这样有点“反直觉”,但在稍大规模的数据下运行时,你会发现这种写法的效率比前者高很多。理解效率提高的原因需要对计算机体系结构和 C/C++ 语言中数组在内存中的存储有一定的了解,这里不作赘述。你可以暂且将其背下来 😂

为了更优雅地实现矩阵快速幂,我们还强烈建议你学习 C++ Class 相关的内容并了解操作符重载。这样你可以自己定义矩阵类并为矩阵类书写乘法规则,从而直接复用“快速幂”一讲中的代码计算矩阵快速幂。下面给出一个参考实现:

class Matrix
{
    int b[10][10];
    Matrix () { memset(b, 0, sizeof(b)); }
    void init_I() { for (int i = 1; i <= n; i++) b[i][i] = 1; }
    Matrix operator * (Matrix other)
    {
        Matrix res;
        for (int i = 1; i <= n; i++)
            for (int k = 1; k <= n; k++)
                for (int j = 1; j <= n; j++)
                    res.b[i][j] += b[i][k] * other.b[k][j];
        return res;
    }
};

Matrix quick_pow(Matrix x, int y)
{
    Matrix res; res.init_I();
    while (y)
    {
        if (y & 1) res = res * x;
        x = x * x; y >>= 1;
    }
    return res;
}
Previous