矩阵乘法与快速幂矩阵

矩阵乘法

51nod 1137 矩阵乘法

(1)矩阵乘法

简单的说矩阵就是二维数组,数存在里面,矩阵乘法的规则:A*B=C

其中c[i][j]为A的第i行与B的第j列对应乘积的和,即:

   模板:

#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
const int maxn=107;
int c[maxn][maxn],a[maxn][maxn],b[maxn][maxn],n;
void multi(int a[][maxn],int b[][maxn],int n)//n是矩阵大小,n<maxn,二维数组传参, 
{                             //第一维可以省略,第二维不可以省略 
    memset(c,0,sizeof c);
    for(int i=0;i<n;i++)
    {
      for(int j=0;j<n;j++)
         {
         	int sum=0;
    	  for(int k=0;k<n;k++)
          sum+=a[i][k]*b[k][j];
          c[i][j]=sum;
		  }
	}
}
int main()
{
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
	 for(int j=0;j<n;j++)
    scanf("%d",&a[i][j]);
	}
	for(int i=0;i<n;i++)
	{
       for(int j=0;j<n;j++)
	  scanf("%d",&b[i][j]);
	}
    multi(a,b,n);
    	for(int i=0;i<n;i++)
	{
       for(int j=0;j<n;j++)
	  printf("%d ",c[i][j]);
	  printf("\n");
	}
	return 0;
}

矩阵快速幂:

51nod 1113 矩阵快速幂

矩阵快速幂类似于普通的快速幂:

ll pow_mod(ll x,ll n)//定义ll为long long,若取x^n的前几位要模一个mod 
{
	ll res=1;
	while(n)
	{
		if(n%2==1)//n&1
		res=res*x;
		x=x*x;
		n/=2;//n<<2=1
	}
	return res;
}

在普通的快速幂中res要初始化 为1,所以矩阵快速幂要把矩阵初始化为单位矩阵(即主对角线为1,其他元素为0)

for(int i=0;i<n;i++) res[i][i]=1;//初始化为单位矩阵

模板:

#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
const int maxn=107;
#define ll long long
ll c[maxn][maxn],a[maxn][maxn],b[maxn][maxn];
int mod=1e9+7,n,m;
void multi(ll a[][maxn],ll b[][maxn],int n)//n是矩阵大小,n<maxn,二维数组传参, 
{                             //第一维可以省略,第二维不可以省略 
    memset(c,0,sizeof c);
    for(int i=0;i<n;i++)
    {
      for(int j=0;j<n;j++)
         {
         	ll sum=0;
    	  for(int k=0;k<n;k++)
          sum+=(a[i][k]*b[k][j])%mod;
          c[i][j]=sum%mod;
		  }
	}
	 for(int i=0;i<n;i++)
	 {
        for(int j=0;j<n;j++)
        a[i][j]=c[i][j]%mod;
	 }
}
long long res[maxn][maxn];
void Pow(ll a[][maxn],int n,int  m) 
{
    memset(res,0,sizeof res);//m是幂,n是矩阵大小
    for(int i=0;i<n;i++) res[i][i]=1;//初始化为单位矩阵 
    while(m)
    {
        if(m%2==1)
         multi(res,a,n);//res=res*a;复制直接在multi里面实现了;
        multi(a,a,n);//a=a*a
        m=m/2;
    }
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		scanf("%lld",&a[i][j]);
	}
	Pow(a,n,m);
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		printf("%lld ",res[i][j]);
		printf("\n");
	}
	return 0;
}

搜了好多代码,大佬们都喜欢用符号重载,这样代码会更加整洁。本弱鸡看不太懂符号重载,以后会慢慢看,下面是大佬的代码,用的符号重载,本篇博客也有些引用大佬博客的思想,感谢大佬。

大佬的代码

快速幂矩阵还有许多应用如:1242 斐波那契数列的第N项

想要了解更多应用推荐看另一个大佬的博客

猜你喜欢

转载自blog.csdn.net/qq_42804678/article/details/81560033
今日推荐