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

    这里先引入一个快速幂

      正常我们计算 x^22次方的话,要怎么去计算,暴力的话平方22次,这里想一个简单的方法,x^22要怎么计算出来, x^22 = x^16 * x^4 * x^2,折几个数怎么来的呢 ? 将22转换为 2进制的数 10110 ,正好不就是2^4 = 16,  2^2 = 4,  2^1 = 2 ;

    快速幂取模

    #define ll long long
    
    ll mod_pow(ll x, ll n, ll mod){
        ll res = 1;
        
        while(n > 0){
            if (n & 1) res = res * x % mod;
            x = x * x % mod;
            n >> 1;
        }
        
        return res;
    }
    

    矩阵快速幂

    1 . 矩阵的定义

      用一个结构体去定义矩阵

      

    struct mat
    {
        int a[2][2];
    };
    

    2 . 矩阵相乘

      学过线代这个就很容易了么,用A矩阵的每一行去乘以B矩阵的每一列,得到一个新的元素。

    代码 :

    struct mat
    {
        int a[2][2];
    };
    
    mat mul(mat a, mat b){ // 以2介矩阵为例
        mat r;
        
      memset(r.a, 0, sizeof(r.a)); // 很重要的一点!!!
        for(int i = 0; i < 2; i++){
            for(int j = 0; j < 2; j++){
                for(int k = 0; k < 2; k++){
                    r.a[i][j] += (a.a[i][k]*b.a[k][j]) % mod;
                    r.a[i][j] %= mod;
                }
            }
        }
        return r;
    }
    // 矩阵相乘的优化,因为矩阵可能会有很多0
    mat mul(mat a, mat b){
        mat r;
        memset(r.a, 0, sizeof(r.a));
        
        for(int i = 0; i < 2; i++){
            for(int k = 0; k < 2; k++){
                if (a.a[i][k]){
                    for(int j = 0; j < 2; j++){
                        if (b.a[k][j]){
                            r.a[i][j] += (a.a[i][k]*b.a[k][j])%mod;
                            r.a[i][j] %= mod;
                        }
                    }
                }
            }
        }
        return r;
    }
    

    3 . 矩阵快速幂

    mat pow(mat A){
        mat B;  // 定义出一个单位矩阵
        
        for(int i = 0; i < 2; i++){  //初始化
            for(int j = 0; j < 2; j++){
                if (i == j) B.a[i][j] = 1;
                else B.a[i][j] = 0;
            }
        }
        
        while(n){
            if (n & 1) B = mul(A, B);
            A = mul(A, A);
            n >>= 1;    // 这里不要写成 >=
        }
        
        return B;
    }
    

    经典的应用 , Fibonacci 数列

    难点的地方就是在于构造矩阵

    东北日出西边雨 道是无情却有情
  • 相关阅读:
    多表查询
    Java基础
    group by 和 having 用法
    多态
    修改用户权限
    集成测试过程
    系统测试
    软件验收测试通过准则
    性能测试、负载测试、压力测试的区别
    白盒测试
  • 原文地址:https://www.cnblogs.com/ccut-ry/p/7818809.html
Copyright © 2011-2022 走看看