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

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

    你学会了吗?

     

    ——抓住了时间,却不会利用的人,终究也逃不过失败的命运。
  • 相关阅读:
    mybatis模糊查询语句
    Java中解压文件名有中文的rar包出现乱码问题的解决
    tomcat服务器开启gzip功能的方法
    asp.net 操作word
    asp.net webservice 返回json数据乱码解决方法
    阿里云服务器mysql修改编码问题
    阿里云服务器问题:访问
    EasyUI 在aspx页面显示高度不正常解决办法
    C# 或 JQuery导出Excel
    如何分离数据库 (SQL Server Management Studio)
  • 原文地址:https://www.cnblogs.com/Nelson992770019/p/11149540.html
Copyright © 2011-2022 走看看