矩阵加速算法:使用矩阵加速数列递推式的计算。

构造矩阵形式递推式

例如递推式:

an=an1+an3,  a1=a2=a3=1

如果直接用这个多项式形式递推式来进行递推,时间复杂度为:O(n),接下来的操作就是为了加速这个过程。

我们列出递推式对应的方程组:

{an=an1+an3an1=an1an2=+an2

写成矩阵形式:

[anan1an2]=[101100010][an1an2an3]

那么即可得到每一项:

[anan1an2]=[101100010]n3[111]

矩阵快速幂

由于矩阵乘法也满足 M2n=(M2)n,因此类比数乘快速幂,矩阵也可以用快速幂算法,只需将数乘换成矩阵乘法即可。

对于上述例子:

[an+3an+2an+1]=Mn[111],  M=[101100010]

通过快速幂来处理 Mn,时间复杂度为 O(logn),实现了递推计算的加速。

模板

n 阶方阵乘法:

vector<vector<ll>> mat_mul(vector<vector<ll>> a, vector<vector<ll>> b, ll mod)
{
    int n = a.size();
    vector<vector<ll>> res(n, vector<ll>(n));
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            for (int k = 0; k < n; k++)
                res[i][j] = (res[i][j] + a[i][k] * b[k][j] % mod) % mod;
    return res;
}

矩阵快速幂:

vector<vector<ll>> mat_pow(vector<vector<ll>> a, ll b, ll mod)
{
    int n = a.size();
    vector<vector<ll>> res(n, vector<ll>(n));
    for (int i = 0; i < n; i++)
        res[i][i] = 1;
    while (b)
    {
        if (b % 2)
            res = mat_mul(res, a, mod);
        a = mat_mul(a, a, mod);
        b /= 2;
    }
    return res;
}