zoukankan      html  css  js  c++  java
  • 矩阵快速幂 ——(递推表达式)

     矩阵快速幂

     

     首先知道矩阵 

         矩阵(Matrix)是一个按照长方阵列排列的复数实数集合;

         矩阵乘法:

    定义:设A
     m×p 
    的矩阵,B
     p×n 
    的矩阵,那么称
     m×n 
    的矩阵C为矩阵AB的乘积,记作
     C=A×B
    ,其中矩阵C中的第
     i 
    行第
     j 
    列元素可以表示为:



    知道矩阵乘法之后,比如菲波那切数列就是一个递推式,
        F(n)=F(n-1)+F(n-2); 因为矩阵乘法,所以

    设 矩阵 A为 
                     
    矩阵 B 为
                      
    则  A*B  则为    F(n)=        F(n-1)*1+F(n-2)*1
    因为我们需要的矩阵为  A*B  的矩阵为  
                                   
    所以倒推到 B 矩阵 ,则 B矩阵是    ,
    所以 F(n) 的矩阵为  初始矩阵   *   (B^(n-2))   n>=3;
    所得到的矩阵  A[0][0]  就是F(n) 的值,时间复杂度优化的地方就是在幂指数的那部分快速幂,节约了时间。
    所以关键就在于  从 递推式构造矩阵 
    比如:

    这个构造出来的矩阵就是

           自己可以写出这个矩阵,就明白了;下面给一个简单的题目,练练手。                                                                                                               



    给一个简单的练习题:   点击打开链接

    #include <cstdio>
    #include <cstring>
    #include <cctype>
    #include <cmath>
    #include <set>
    #include <map>
    #include <list>
    #include <queue>
    #include <deque>
    #include <stack>
    #include <string>
    #include <bitset>
    #include <vector>
    #include <iostream>
    #include <algorithm>
    #include <stdlib.h>
    
    
    using namespace std;
    typedef long long LL;
    const int INF=2e9+1e8;
    const int MOD=1000007;
    const int MAX_SIZE=1005;
    const int MM=3;
    
    
    LL f1,f2,a,b,c,n;
    
    
    struct Mat
    {
        LL maze[MM][MM];
        void set_empty()
        {
            memset(maze,0,sizeof(maze));
        }
    };
    Mat unit_Mat=
    {
        1,0,0,
        0,1,0,
        0,0,1
    };   //  定义一个单位矩阵,任何一个矩阵 乘以 单位矩阵,其值等于本身;
    Mat operator *(Mat a,Mat b)  // 重载运算符  * //  定义两个矩阵的乘法,根据矩阵乘法的定义来写
    {
        Mat c;
        c.set_empty();  // 一定要设置为空。清零数组;不然后面加等一个数会有垃圾值
        LL i,j,k;
        for(i=0; i<MM; i++)
        {
            for(j=0; j<MM; j++)
            {
                for(k=0; k<MM; k++)
                {
                    c.maze[i][j]+=a.maze[i][k] * b.maze[k][j];
                    c.maze[i][j] %= MOD;
                }
            }
        }
        return c;
    }
    Mat operator^(Mat a,LL N)  //  优化时间的就在此处,
    //  类似与一般的int 数字的快速幂求值,思想是一样的。不懂可百度快速幂。
    {
        Mat c=unit_Mat;
        while(N)
        {
            if(N&1) c=a*c;
            a=a*a;
            N>>=1;
        }
        return c;
    }
    void solve()
    {
        Mat A,B;
        B.set_empty();
        A.set_empty();
        B.maze[0][0]=b,B.maze[1][0]=a,B.maze[2][0]=c;
        B.maze[0][1]=B.maze[2][2]=1;
        B=B^(n-2);
        A.maze[0][0]=f2,A.maze[0][1]=f1,A.maze[0][2]=1;
        LL ans=0;
        Mat C=A*B;
        printf("%lld
    ",(C.maze[0][0]+MOD)%MOD);
    }
    int main()
    {
        int times;
        scanf("%d",&times);
        while(times--)
        {
            scanf("%lld %lld %lld %lld %lld %lld",&f1,&f2,&a,&b,&c,&n);
            if(n == 1)
                printf("%lld
    ",(f1+MOD)%MOD);
            else if(n == 2)
                printf("%lld
    ",(f2+MOD)%MOD);
            else solve();  // 其上位特判 因为公式的定义域是  n>=3;
        }
        return 0;
    }
    


  • 相关阅读:
    动态生成 Excel 文件供浏览器下载的注意事项
    JavaEE 中无用技术之 JNDI
    CSDN 泄露用户密码给我们什么启示
    刚发布新的 web 单点登录系统,欢迎下载试用,欢迎提建议
    jQuery jqgrid 对含特殊字符 json 数据的 Java 处理方法
    一个 SQL 同时验证帐号是否存在、密码是否正确
    PostgreSQL 数据库在 Windows Server 2008 上安装注意事项
    快速点评 Spring Struts Hibernate
    Apache NIO 框架 Mina 使用中出现 too many open files 问题的解决办法
    解决 jQuery 版本升级过程中出现 toLowerCase 错误 更改 doctype
  • 原文地址:https://www.cnblogs.com/coded-ream/p/7207987.html
Copyright © 2011-2022 走看看