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

    处理何种问题:用于优化加速一些线性关系式,可将一些时间复杂度降至O(logn)。

    (如果题目上出现 1e18 之类的数据范围,就可以往矩阵快速幂上想了)

     

    性能:具体的时间复杂度为O(edge * edge * log n),edge为矩阵的阶数。

     

    原理:矩阵乘法性质、快速幂。

     

    实现步骤:以斐波那契数列为例

    公式为: F[i] = F[i-1] + F[i-2],根据公式将此转化为矩阵公式

     

     

    备注:需要进行 *、= 符号的重载,套用快速幂模板,但取模在 * 重载函数中。

     

    输入样例解释

    99999999999999  //f(n)

     

    输出样例解释

    626  //结果

    --------------------------------------------------------------------

    代码

    ///此代码为求斐波那契数列矩阵快速幂,若要求其他矩阵快速幂注意更改标记   <--- 的行。
    #include<iostream>
    #include<cstdio>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    
    const long long mod=10000;/// <---
    const int edge=2;/// <---
    
    struct Matrix ///定义矩阵,重载*,=;
    {
        long long a[edge][edge];
        Matrix()
        {
            memset(a,0,sizeof(a));///构造函数,初始化矩阵
        }
        Matrix operator *(const Matrix b) ///自定义矩阵乘法
        {
            Matrix temp;
            for(int i=0; i<edge; ++i)
                for(int j=0; j<edge; ++j)
                    for(int k=0; k<edge; ++k)
                    {
                        temp.a[i][j]+=a[i][k]*b.a[k][j];
                        temp.a[i][j]%=mod;///在此取模
                    }
            return temp;
        }
    };
    
    Matrix m_fpow(Matrix a,long long n)
    {
        Matrix Ans;
    
        Ans.a[0][0]=Ans.a[1][1]=1;///初始化为单位矩阵    // <---
    
        while(n!=0)///套用快速幂
        {
            if(n&1)
                Ans=Ans*a;
            n=n>>1;
            a=a*a;
        }
        return Ans;
    }
    
    int main()
    {
        Matrix Ans,a,b;
        long long n;
    
        scanf("%lld",&n);
        if(n==0)
            printf("0
    ");
        else if(n==1)
            printf("1
    ");
        else
        {
            a.a[0][0]=a.a[0][1]=a.a[1][0]=1;///初始化,不同的dp关系对应不同的矩阵    // <---
            b.a[0][0]=b.a[1][0]=1;                                                    /// <---
            Ans=m_fpow(a,n-2)*b;
            printf("%lld
    ",Ans.a[0][0]);
        }
        return 0;
    }
    

      

  • 相关阅读:
    BUUCTF--Youngter-drive
    BUUCTF--CrackRTF
    FireShell CTF 2020 Re Simple Encryption
    2020 美国大学生数学建模论文翻译(week 2)
    仿射密码
    乘法逆元
    RC4加密与解密
    2020 BJDCTF Re encode
    2020美国大学生数学建模(MCM/ICM)A题数据及参考资料
    路由器, 美团笔试题, 差分
  • 原文地址:https://www.cnblogs.com/l1l1/p/8719294.html
Copyright © 2011-2022 走看看