矩阵乘法&快速幂&重载运算符式实现

线性代数里一个很重要的概念就是矩阵 ,在解算法题中矩阵也有很大的用处,比如说二维前缀和矩阵。

而矩阵里比较难以实现的一种运算法则就是矩阵的乘法,涉及乘法也必然涉及幂的问题。下面就有一种实现矩阵乘法和矩阵快速幂的方法。

首先我们先来看一下矩阵乘法的定义:

A为  的矩阵,B为  的矩阵,那么称  的矩阵C为矩阵AB的乘积,记作  ,其中矩阵C中的第 

行第  列元素可以表示为:

简单记忆为:前列等后行(可以相乘的条件),前行乘后列(这代表了矩阵的大小,也代表对于每个aij,i行与j列分别对应相乘再相加)。

既然我们要用到快速幂,众所周知我们要先定义一个初始值为1的接收答案的变量,那么我们怎么去找这样一个“1”去接收矩阵的乘积呢?答案就是—符合乘法条件的单位矩阵。什么是单位矩阵?

如上图,主对角线元素全为1,且其他位置的元素全是0的矩阵叫做单位矩阵,任何矩阵乘以这种单位矩阵都是它自身。

还有一个小操作是重载运算符,这个操作的意义是给某个运算符赋予一个新的意义,一般格式如下:

bool opreator (sign) (datatype name, datatype name)
{
    function body;
}

下面来看一下详细的实现代码

#include 
#include 
#include 
#include 
#include 
#include 
#define DETERMINATION main
#define lldin(a) scanf("%lld",&a)
#define din(a) scanf("%d",&a)
#define reset(a,b) memset(a,b,sizeof(a))
const int INF=0x3f3f3f3f;
using namespace std;
typedef long long ll;
typedef long double ld;
/*Although there will be many obstructs ahead of you,
the desire for victory still fills you with determination..*/
typedef struct
{
       int mat[50][50];
       int n,m;
} matrix;
//由于二维数组传递参数有限制(必须确定列数),所以我们把它放在结构体里。
matrix ma,mb,mc;
matrix multipy(matrix a, matrix b)//矩阵乘法
//重载运算符式写法:bool opreator *(matrix a,matrix b)
{
        matrix ans;
        reset(ans.mat,0);//!!!!必须清空这个临时矩阵
        if(a.m==b.n)//前矩阵的列等于后矩阵的行乘法才有意义。
           
    {
                ans.n=a.n,ans.m=b.m;//确定大小
                for(int i=1; i<=a.n; i++)
                        for(int j=1; j<=b.m; j++)
                            {
                                for(int k=1; k<=a.m; k++)
                                        ans.mat[i][j]+=a.mat[i][k]*b.mat[k][j];//模拟矩阵乘法,算法复杂度为n的立方。
                           
            }
           
    }
       return ans;//这里返回了一个结构体,内含乘后的矩阵。
}
matrix quickpower(int x,matrix tar)//矩阵快速幂
{
        matrix res;
        res.n=tar.n;
        res.m=tar.m;//把当前矩阵设定为等行列的单位矩阵
        reset(res.mat,0);
        for(int i=1; i<=res.n; i++)
                for(int j=1; j<=res.m; j++)
                   
        {
                        if(i==j)
                                res.mat[i][j]=1;
                        else
                                res.mat[i][j]=0;
                   
        }
        while(x)//常规快速幂
           
    {

                if(x&1)
                    res=multipy(res,tar);//重载运算符后为res*tar
                if(!(x&1))
                    tar=multipy(tar,tar);//重载运算符后为tar*tar
                x>>=1;

           
    }
        return res;
}
int DETERMINATION()
{
        cin>>ma.n>>ma.m;
        for(int i=1; i<=ma.n; i++)
                for(int j=1; j<=ma.m; j++)
                        cin>>ma.mat[i][j];
        mc=quickpower(2,ma);
        for(int i=1; i<=mc.n; i++)
           
    {
              for(int j=1; j<=mc.m; j++)
                  cout<

 

你可能感兴趣的:(矩阵快速幂)