ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

归档:220813 | 社恐铁锹的第一次新知讲授:矩阵快速幂

2022-08-16 00:33:11  阅读:173  来源: 互联网

标签:return Mat 社恐 namespace 220813 矩阵 int 新知 mod


铁锹:呃,其实我的名字是英文缩写,不是铁锹,你们不要再给我乱起外号了


什么是矩阵?

一个 \(n\times m\) 的矩阵是由数组成的 \(n\) 行 \(m\) 列的方阵。

什么是矩阵乘法?

假设有三个矩阵 \(A, B, C\),其中 \(A\) 的列数与 \(B\) 的行数相等(假设为 \(n\))。若 \(C=A\times B\),那么 \(C_{i,j}=\sum\limits_{k=1}^n A_{i,k}\times B_{k,j}\),其中 \(C\) 的行数与 \(A\) 的行数相等,\(B\) 的列数与 \(C\) 的列数相等。

什么是矩阵快速幂?

把普通快速幂的底数换成矩阵。

铁锹:呃我要讲的就是这些,同学们可以开始做题了。


呃呃,所以模拟一下这个过程就好了?

namespace Matrix {
const int maxn = 25;
template<const int mod>
class Mat {
private:
    int n, m;
public:
    int a[maxn][maxn];
    Mat () {}
    Mat (int N, int M, bool type = 0) {
        n = N, m = M;
        memset(a, 0, sizeof (a));
        if (type) {
            for (int i = 1; i <= n; ++i)
                a[i][i] = 1;
        }
    }
    int* operator[] (int q) {
        return a[q];
    }
    const int* operator[] (int q) const {
        return a[q];
    }
    Mat operator* (const Mat &q) const {
        Mat res(n, q.m);
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= q.m; ++j) {
                for (int k = 1; k <= m; ++k) {
                    (res[i][j] += (a[i][k] 
                        * q[k][j] % mod + mod)
                        % mod) %= mod;
                }
            }
        }
        return res;
    }
    Mat& operator*= (const Mat &q) {
        return (*this) = (*this) * q;
    }
    Mat operator^ (const int q) const {
        int y = q;
        Mat res(n, n, 1), x(*this);
        while (y) {
            if (y & 1)
                res *= x;
            x *= x;
            y >>= 1;
        }
        return res;
    }
    Mat& operator^= (const int &q) {
        return (*this) = (*this) ^ q;
    }
};
} // namespace Matrix

CF450B - Jzzhu and Sequences

游戏的第一关都会放一个稀奇古怪的东西让新手入门。

——我也不知道是哪位 TFer 说的

我看了大半天没看懂样例最后发现不是斐波那契???

那也和斐波那契一样啊。

我们都知道,斐波那契的加速矩阵是这样的:

\[[f_{i - 1},f_i]=[f_i,f_{i + 1}]\times\begin{bmatrix}0&1\\1&1 \end{bmatrix} \]

那我们把 \(f_{i-1}\to f_{i+1}\) 的系数改成减就好了。

namespace XSC062 {
using namespace fastIO;
using namespace Matrix;
const int mod = 1e9 + 7;
int x, y, m;
Mat<mod> A, B;
int main() {
    read(x);
    read(y);
    read(m);
    if (m == 1) {
        printf("%lld", (x % mod + mod) % mod);
        return 0;
    }
    if (m == 2) {
        printf("%lld", (y % mod + mod) % mod);
        return 0;
    }
    A = Mat<mod>(1, 2);
    B = Mat<mod>(2, 2);
    A[1][1] = x;
    A[1][2] = y;
    B[1][2] = -1;
    B[2][1] = B[2][2] = 1;
    A *= (B ^= (m - 2));
    printf("%lld", A[1][2]);
    return 0;
}
} // namespace XSC062

标签:return,Mat,社恐,namespace,220813,矩阵,int,新知,mod
来源: https://www.cnblogs.com/XSC062/p/16590168.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有