码迷,mamicode.com
首页 > 其他好文 > 详细

【总结】矩阵快速幂

时间:2020-01-17 23:15:28      阅读:77      评论:0      收藏:0      [点我收藏+]

标签:学习   如何   ret   了解   问题   long   base   次方   str   

在学习矩阵快速幂之前,首先我们需要分别了解快速幂和矩阵乘法

快速幂

快速幂要求解的是这样一类问题:

给你A,B,C,求A的B次方模C的余数

A,C<=10^9,B<=10^18

如果我们线性去求,时间复杂度是O(n)的,但题目中给出的B是很大的数,这样显然会超时,我们可以用快速幂来加速这个过程。

我们可以想像一下小学的时候我们如何计算2^16

2^16=4^8=16^4=256^2=65536

那如何计算2^18呢?

2^18=4^9=44^8=416^4=4256^2=465536=262144

快速幂同理也是如此

我们可以按照上面做法,利用分治的思想求去解

这样原本O(n)的时间复杂度便降到了O(log n )

long long ans=1,base=a;
while(n>0){
        if(n&1){
            ans*=base;
        }
        base*=base;
        n=n/2;
    }

矩阵乘法

矩阵乘法可以先稍作了解,知道矩阵相乘的运算法则

技术图片

?\(C[i][j]= A[i][k]B[k][j]\)

矩阵快速幂

矩阵快速幂的原理同快速幂一样,只是转换为了矩阵之间的乘法操作

所以单纯的重载一下运算符,将普通的乘法转换为矩阵乘法就好了。

嗯,看一下代码就应该很好理解了x

#include<iostream>
#include<cstdio>
#include<cctype>
#define ll long long
#define Mod 1000000007
using namespace std;
ll read(){
    ll a=0;int f=0;char p=getchar();
    while(!isdigit(p)){f|=p=='-';p=getchar();}
    while(isdigit(p)){a=(a<<3)+(a<<1)+(p^48);p=getchar();}
    return f?-a:a;
}
ll n,k;
struct mat{
    ll m[101][101];
}a,b,c,e;
mat mul(mat x,mat y){
    mat k;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            k.m[i][j]=0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            for(int q=1;q<=n;q++)
                k.m[i][j]=k.m[i][j]%Mod+x.m[i][q]%Mod*y.m[q][j]%Mod;
    return k;
}
mat pow(mat x,ll y){
    mat ans=b;
    while(y){
        if(y&1)ans=mul(ans,x);
        x=mul(x,x);
        y>>=1;
    }
    return ans;
}
int main(){
    n=read();k=read();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            a.m[i][j]=read();
    for(int i=1;i<=n;i++)b.m[i][i]=1;
    mat ans=pow(a,k);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++)
            cout<<ans.m[i][j]%Mod<<" "; 
        cout<<endl;
    }
}

【总结】矩阵快速幂

标签:学习   如何   ret   了解   问题   long   base   次方   str   

原文地址:https://www.cnblogs.com/huixinxinw/p/12207565.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!