矩阵快速幂

对于矩阵快速幂,其作用能够达到快速递推公式的作用

这里先定义一个矩阵

struct martix{
    int x[105][105];
    martix(){memset(x,0,sizeof x);}
};

首先看如何进行矩阵计算,由线性代数知:

martix cacl(martix a,martix b){
    martix c;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            for(int k=1;k<=n;k++)
                c.x[i][j]=(c.x[i][j]%mod+a.x[i][k]%mod*b.x[k][j]%mod)%mod;
    return c;
}

那么如何快速求出 $k$ 个矩阵的相乘呢? 我们可以回忆数字的快速幂,普通的快速幂是把 $k$ 化成二进制,即

int qpow(int a,int k){
    int res=1;;
    while(k){
        if(k&1) res*=a,res%=mod;
        k>>=1,a*=a,a%=mod;
    }
    return res;
}

阵快速幂与其类似,也就把次方数进行二进制计算

martix qpow(martix mp,int k){
    martix res;
    for(int i=1;i<=n;i++) res.x[i][i]=1;
    while(k){
        if(k&1) res=cacl(mp,res);
        k>>=1,mp=cacl(mp,mp);
    }
    return res;
}

模板:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10,mod=1e9+7;
int n,k;
struct martix{
    int x[105][105];
    martix(){memset(x,0,sizeof x);}
};
martix cacl(martix a,martix b){
    martix c;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            for(int k=1;k<=n;k++)
                c.x[i][j]=(c.x[i][j]%mod+a.x[i][k]%mod*b.x[k][j]%mod)%mod;
    return c;
}
martix qpow(martix mp,int k){
    martix res;
    for(int i=1;i<=n;i++) res.x[i][i]=1;
    while(k){
        if(k&1) res=cacl(mp,res);
        k>>=1,mp=cacl(mp,mp);
    }
    return res;
}
signed main()
{
    std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    cin>>n>>k;
    martix mp;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++) cin>>mp.x[i][j];
    martix res=qpow(mp,k);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++) cout<<res.x[i][j]%mod<<' ';
        cout<<endl;
    }
    return 0;
}

矩阵快速幂的应用: 【朝夕的ACM笔记】杂项-矩阵快速幂 - 知乎 (zhihu.com)

 

posted @ 2024-03-03 18:24  o-Sakurajimamai-o  阅读(12)  评论(0编辑  收藏  举报
-- --