矩阵快速幂

矩阵快速幂

矩阵:

一个矩阵 A A A,是由 n × m n\times m n×m 个数字组成, B B B m × p m\times p m×p 组成,详见下。
A = [ a 1 , 1 , a 1 , 2 , a 1 , 3 ⋯ a 1 , m a 2 , 1 , a 2 , 2 , a 2 , 3 ⋯ a 2 , m ⋅ ⋅ ⋅ a n , 1 , a n , 2 , a n , 3 ⋯ a n , m ] B = [ b 1 , 1 , b 1 , 2 , b 1 , 3 ⋯ b 1 , p b 2 , 1 , b 2 , 2 , b 2 , 3 ⋯ b 2 , p ⋅ ⋅ ⋅ b m , 1 , b m , 2 , b m , 3 ⋯ b m , p ] A=\begin{bmatrix}a_{1,1},a_{1,2},a_{1,3}\cdots a_{1,m} \\ a_{2,1},a_{2,2},a_{2,3}\cdots a_{2,m} \\ \cdot \\ \cdot \\ \cdot \\ a_{n,1},a_{n,2},a_{n,3}\cdots a_{n,m}\end{bmatrix} \\ \\ B=\begin{bmatrix}b_{1,1},b_{1,2},b_{1,3}\cdots b_{1,p} \\ b_{2,1},b_{2,2},b_{2,3}\cdots b_{2,p} \\ \cdot \\ \cdot \\ \cdot \\ b_{m,1},b_{m,2},b_{m,3}\cdots b_{m,p} \end{bmatrix} A= a1,1,a1,2,a1,3a1,ma2,1,a2,2,a2,3a2,man,1,an,2,an,3an,m B= b1,1,b1,2,b1,3b1,pb2,1,b2,2,b2,3b2,pbm,1,bm,2,bm,3bm,p
注意到, A A A 的列数与 B B B 的行数均为 m m m,将其定义为可以进行矩阵乘法的两个矩阵

如何相乘?

若其乘积为矩阵 C C C,则 C C C 为一个 n × p n\times p n×p 的矩阵,乘积过程为:
c i , j = ∑ k = 1 m a i , k × b k , j c_{i,j}=\sum_{k=1}^{m} a_{i,k}\times b_{k,j} ci,j=k=1mai,k×bk,j
代码:

for(int k=1;k<=n;k++)
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            c[i][j]+=a[i][k]*b[k][j];

这不就是Floyd吗。。

A A A 描述成 n n n 个行向量的集合, B B B 表示为 p p p 个列向量的集合,如下。
A = [ a 1 a 2 a 3 ⋅ ⋅ ⋅ a n ] B = [ b 1 , b 2 , b 3 ⋯ b p ] A=\begin{bmatrix} a_1 \\ a_2 \\ a_3 \\ \cdot \\ \cdot \\ \cdot \\ a_n \end{bmatrix} \\ \\ \\ B=\begin{bmatrix} b_1,b_2,b_3 \cdots b_p \end{bmatrix} A= a1a2a3an B=[b1,b2,b3bp]
C C C 为:
C = [ a 1 × b 1   ,   a 1 × b 2   ,   a 1 × b 3 ⋯ a 1 × b p a 2 × b 1   ,   a 2 × b 2   ,   a 2 × b 3   , ⋯ a 2 × b p ⋅ ⋅ ⋅ a n × b 1   ,   a n × b 2   ,   a n × b 3 ⋯ a n × b p ] C=\begin{bmatrix}a_1\times b_1\ ,\ a_1\times b_2\ ,\ a_1\times b_3\cdots a_1\times b_p \\ a_2\times b_1\ ,\ a_2\times b_2\ ,\ a_2\times b_3\ ,\cdots a_2\times b_p \\ \cdot \\ \cdot \\ \cdot \\ a_n\times b_1\ ,\ a_n\times b_2\ ,\ a_n\times b_3\cdots a_n\times b_p \end{bmatrix} C= a1×b1 , a1×b2 , a1×b3a1×bpa2×b1 , a2×b2 , a2×b3 ,a2×bpan×b1 , an×b2 , an×b3an×bp

上文提到,若 A A A B B B 有一个 m m m 相等,则它们有一个单位元,可以使其相乘后不影响结果。

更清楚的具体方法如下,可以更好地解释上句话。

  • A A A 的每个成员去匹配 B B B​ 的每个成员
例题:P3390 【模板】矩阵快速幂
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7,MAXN=105;
ll n,m;
ll ans[MAXN][MAXN],a[MAXN][MAXN],t[MAXN][MAXN];
inline void mul1()
{
	memset(t,0,sizeof(t));
	for(ll k=1;k<=n;k++)
		for(ll i=1;i<=n;i++)
			for(ll j=1;j<=n;j++)
				t[i][j]=(t[i][j]+ans[i][k]*a[k][j])%mod;
	for(ll i=1;i<=n;i++)
		for(ll j=1;j<=n;j++)
			ans[i][j]=t[i][j];
	return;
}
inline void mul2()
{
	memset(t,0,sizeof(t));
	for(ll k=1;k<=n;k++)
		for(ll i=1;i<=n;i++)
			for(ll j=1;j<=n;j++)
				t[i][j]=(t[i][j]+a[i][k]*a[k][j])%mod;
	for(ll i=1;i<=n;i++)
		for(ll j=1;j<=n;j++)
			a[i][j]=t[i][j];
	return;
}
inline void quickpow()
{
	while(m)
	{
		if(m&1)
			mul1();
		mul2();//千万不能加else!!!(血泪教训)
		m>>=1;
	}
	return;
}
int main(){
	scanf("%lld%lld",&n,&m);
	for(ll i=1;i<=n;i++)
		for(ll j=1;j<=n;j++)
			scanf("%lld",&a[i][j]);
	for(ll i=1;i<=n;i++)
		ans[i][i]=1;
	quickpow();
	for(ll i=1;i<=n;i++)
	{
		for(ll j=1;j<=n;j++)
			printf("%lld ",ans[i][j]%mod);
		putchar('\n');
	}
	return 0;
}

  • 8
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值