• 矩阵快速幂的总结以及模版


    jun 碰到了挺多数列的题,线性递推,值又很大,直接推会超时,所以去网上找题解的时候,找到了矩阵快速幂以及杜教板子,杜教板子还没看懂,就以后再发

    首先,快速幂,之前也学了整数的快速幂,复杂度是O(log^2n)这里就把模版贴一下

    int poww(int a,int b){
        int ans=1,base=a;
        while(b!=0){
            if(b&1!=0)
              ans*=base;
            base*=base;
            b>>=1;
      }
        return ans;
    }

    然后对于矩阵快速幂,只需要在快速幂中将两个整数a ,b改成矩阵形式就行了,然后相乘需要改成矩阵相乘

    const int maxn=3;
    const int mod=1000000007;
    struct matrix{
        long long a[maxn][maxn];
        void init(){
            memset(a,0,sizeof(a));
            for(int i=0;i<maxn;i++) a[i][i]=1;
        }
    };
    matrix mul(matrix a,matrix b){
        matrix ans;
        for(int i=0;i<maxn;++i){
            for(int j=0;j<maxn;++j){
                ans.a[i][j] = 0;
                for(int k=0;k<maxn;++k){
                    ans.a[i][j]=(ans.a[i][j]+a.a[i][k]*b.a[k][j]+mod)%mod;
                }
            }
        }
        return ans;
    }
    matrix qpow(matrix a, int n){
        matrix ans;
        ans.init();
        while(n){
            if(n&1) ans = mul(ans, a);
            a=mul(a,a);
            n/=2;
        }
        return ans;
    }

    然后对于矩阵快速幂的运用来说,一般上用于线性递推的数列求第n项和

    比如巨大的斐波拉契数列,如果直接用f(n)=f(n-1)+f(n-2)的话会超时,而如果用矩阵快速幂的形式去算的的话复杂度会降很多

    即矩阵形式就是

    然后只需要对前面的那个矩阵求(n-1)次方就行了

    还有的题目是需要自己去推的矩阵形式

    列出最近写的两个题

    一道是hdu的6185http://acm.hdu.edu.cn/showproblem.php?pid=6185

    一道是牛客网小白赛6的洋灰三角https://www.nowcoder.com/acm/contest/136/J

    第二题是需要求前n项和的但是解法还是相似的,递推式就是sum(n)=sum(n-1)+f(n)

    就把第二题的代码附一下吧

    #include <cstdio>
    #include <iostream>
    #include <string>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <map>
    #include <stack>
    #define INF 1e9
    using namespace std;
    const int maxn=3;
    const int mod=1000000007;
    struct matrix{
        long long a[maxn][maxn];
        void init(){
            memset(a,0,sizeof(a));
            for(int i=0;i<maxn;i++) a[i][i]=1;
        }
    };
    matrix mul(matrix a,matrix b){
        matrix ans;
        for(int i=0;i<maxn;++i){
            for(int j=0;j<maxn;++j){
                ans.a[i][j] = 0;
                for(int k=0;k<maxn;++k){
                    ans.a[i][j]=(ans.a[i][j]+a.a[i][k]*b.a[k][j]+mod)%mod;
                }
            }
        }
        return ans;
    }
    matrix qpow(matrix a, int n){
        matrix ans;
        ans.init();
        while(n){
            if(n&1) ans = mul(ans, a);
            a=mul(a,a);
            n/=2;
        }
        return ans;
    }
    int main()
    {
        matrix ans,res;
        int n,k,q;
        memset(ans.a,0,sizeof(ans.a));
        memset(res.a,0,sizeof(res.a));
        cin>>n>>k>>q;
        if(n==1){
            cout<<1<<endl;
            return 0;
        }
        ans.a[0][0]=1;ans.a[0][1]=1;ans.a[1][1]=k;
        ans.a[1][2]=1;ans.a[2][2]=1;
        res=qpow(ans,n);
        long long s=res.a[0][0]*1l%mod+res.a[0][1]*1l%mod+res.a[0][2]*q%mod;
        cout<<s%mod-1<<endl;
    }
  • 相关阅读:
    BADI 笔记
    ALV 常用功能 转载
    F4字段搜索帮助
    全省各地均可拨打劳动违法投诉电话:12333
    小结SQL Server连接失败错误及解决
    sql server日志已满处理方法
    VC6.0快捷键大全
    Eclipse下UML插件及安装
    Delphi错误:"External exception C0000235"
    delphi中临界操作方法
  • 原文地址:https://www.cnblogs.com/maybe96/p/9504917.html
Copyright © 2020-2023  润新知