zoukankan      html  css  js  c++  java
  • 【矩阵专题】——矩阵快速幂

    今天来讲矩阵快速幂:

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

    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;
    }

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

    你学会了吗?

     

    ——抓住了时间,却不会利用的人,终究也逃不过失败的命运。
  • 相关阅读:
    深入理解委托、匿名方法和 Lambda 表达式
    常见SQL问题
    LeetCode题解——四数之和
    把中台说清楚
    程序员们的三高:高并发、高性能、高可用
    论文查重是怎么查的
    LeetCode题解——最长回文子串
    六百字读懂 Git(转)
    SQL中ON和WHERE的区别
    链表排序之堆排序
  • 原文地址:https://www.cnblogs.com/Nelson992770019/p/11149540.html
Copyright © 2011-2022 走看看