【矩阵专题】——矩阵快速幂

今天来讲矩阵快速幂:

先卖个关子,对于一般的快速幂,我们是这样解决的:

eg:n19 mod k

我们知道,根据二进制

19(10)=10011(2)=(10000+10+1)(2)

所以可以将19二进制分解

这里引入res和ans和N三个变量。

令N=19,res=n,ans=1

10011末尾为1,所以将这个单独放入ans:ans=res*ans=n,接着将res平方:res=res*res=n2将N右移一位:N>>=1。

1001:ans=res*ans=n3;res=res2=n4

100:末尾为0,不改变ans,但将res平方:res=n8

10:res=n16

1:ans=n3+16=19,;res=n32

最后我们得到结果。

时间复杂度:O(log₂N)。

上代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,k;
ll quickpow(ll x,ll N){
    ll res = x,ans = 1;
    while(N){
        if(N & 1){
            ans = ans * res;
        }
        res *= res;
        N >>= 1;
    }
    return ans;
}
int main(){
    scanf("%lld%lld",&n,&k);
    printf("%lld\n",quickpow(n,k));
    return 0;
}

这是对于数字的快速幂,那么矩阵呢?

其实是一样的,我们将矩阵乘法代替乘号,ans变为单位矩阵I,其余不变。

上代码:

 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7; 
const ll maxn=110;
ll n,k;
struct matrix{
    ll a[maxn][maxn];
    void Empty(){
        memset(a,0,sizeof(a));
    }
    void One(){
        Empty();
        for(ll i=1;i<=n;i++) a[i][i]=1; 
    }
    matrix operator *(matrix b){
        matrix tmp;
        tmp.Empty();
        for(ll i=1;i<=n;i++){
            for(ll j=1;j<=n;j++){
                for(ll q=1;q<=n;q++){
                    (tmp.a[i][j]+=a[i][q]*b.a[q][j]%mod)%=mod;
                }
            }
        }
        return tmp;
    }
    void out(){
        for(ll i=1;i<=n;i++){
            for(ll j=1;j<=n;j++){
                printf("%lld ",a[i][j]%mod);
            }
            printf("\n");
        }
    }
}res,ans;
void matrix_pow(ll N){
    ans.One();
    while(N){
        if(N&1){
            ans=ans*res;
        }
        res=res*res;
        N>>=1;
    }
}
int main(){
    scanf("%lld%lld",&n,&k);
    for(ll i=1;i<=n;i++){
        for(ll j=1;j<=n;j++){
            scanf("%lld",&res.a[i][j]);
        }
    }
    matrix_pow(k);
    ans.out();
    return 0;
}

 

另外我们可以在矩阵中写一些函数便于操作,比如单位矩阵,矩阵乘法,矩阵清零,矩阵输出等。

你学会了吗?

 

posted @ 2019-07-08 10:13  Nelson992770019  阅读(206)  评论(0编辑  收藏  举报