zoukankan      html  css  js  c++  java
  • 矩阵快速幂

    应用场景

    计算超大数据范围内的斐波那契数列

    算法原理

    根据公式(f[n] = f[n - 1] + f[n - 2])
    我们如果想要计算(f[n])的值,需要通过(f[n - 1])(f[n - 2])
    那么通过两个矩阵的运算即可达到我们的目的

    • 矩阵1:

    [egin{bmatrix} f[n - 2] & f[n - 1] end{bmatrix} ]

    • 矩阵2:

    [egin{bmatrix} 0 & 1 \ 1 & 1 end{bmatrix} ]

    • 矩阵1 * 矩阵2的结果

    [egin{bmatrix} f[n - 1] & f[n] end{bmatrix} ]

    如果想要计算前n项的和,我们还需要向矩阵中增添元素

    • 矩阵1:

    [egin{bmatrix} f[n - 1] & f[n] & s[n - 1] end{bmatrix} ]

    矩阵1之所以这样定义,是因为初始状态是下面这样的

    [egin{bmatrix} f[1] & f[2] & s[1] end{bmatrix} ]

    • 矩阵2:

    [egin{bmatrix} 0 & 1 & 0\ 1 & 1 & 1 \ 0 & 0 & 1 end{bmatrix} ]

    • 矩阵1 * 矩阵2的结果

    [egin{bmatrix} f[n] & f[n + 1] & s[n] end{bmatrix} ]

    代码实现

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    
    using namespace std;
    
    typedef long long LL;
    
    const int N = 3;
    
    int n, m;
    
    void mul(int c[][N], int a[][N], int b[][N]) // c = a * b
    {
        int temp[N][N] = {0};
        
        // 手算的过程就是先选定a中的一行,然后遍历b的所有列,所以按照如下
        for (int i = 0; i < N; ++ i) // 选择a的行
            for (int j = 0; j < N; ++ j) // 选择b的列
                for (int k = 0; k < N; ++ k) // 选择a的列和b的行
                    temp[i][j] = (temp[i][j] + (LL)a[i][k] * b[k][j]) % m;
        
        memcpy(c, temp, sizeof temp);
    }
    int main()
    {
        cin >> n >> m;
        
        int f[N][N] = {1, 1, 1};
        int a[N][N] = {
            {0, 1, 0},
            {1, 1, 1},
            {0, 0, 1}
        };
        
        -- n; // 计算s[1]需要乘以a 0 次,所以计算s[n]需要乘以a n-1次
        // 计算f*a^n
        while (n)
        {
            if (n & 1) mul(f, f, a);
            mul(a, a, a);
            n >>= 1;
        }
        
        cout << f[0][2] << endl;
        
        return 0;
    }
    
  • 相关阅读:
    闭包 (Closure)
    RSA算法
    HTTPS
    SSH
    HDU1754 I hate it_线段树(入门级别)
    HDU1166 敌兵布阵_线段树
    c++运算符优先级表
    归并排序练习.
    HDU 1969 精度二分
    uva10944 状态压缩bfs or DP
  • 原文地址:https://www.cnblogs.com/G-H-Y/p/14534784.html
Copyright © 2011-2022 走看看