矩阵快速幂(重载运算符,矩阵乘法)

上一篇写了快速幂[模板] ,这篇是有关拓展,矩阵快速幂=矩阵乘法+快速幂。下面是洛谷里的一道模板题,写之前要了解矩阵乘法。关于重载运算符,这里用不用都行。

【模板】矩阵快速幂

题目描述

给定 n × n n\times n n×n 的矩阵 A A A,求 A k A^k Ak

输入格式

第一行两个整数 n , k n,k n,k
接下来 n n n 行,每行 n n n 个整数,第 i i i 行的第 j j j 的数表示 A i , j A_{i,j} Ai,j

输出格式

输出 A k A^k Ak

n n n 行,每行 n n n 个数,第 i i i 行第 j j j 个数表示 ( A k ) i , j (A^k)_{i,j} (Ak)i,j,每个元素对 1 0 9 + 7 10^9+7 109+7 取模。

【数据范围】

对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 100 1\le n \le 100 1n100 0 ≤ k ≤ 1 0 12 0 \le k \le 10^{12} 0k1012 ∣ A i , j ∣ ≤ 1000 |A_{i,j}| \le 1000 Ai,j1000

代码

#include<iostream>
#include<cstring>
#define ll long long 
const ll N=1e9+7;
ll n;
using namespace std;
typedef struct {
	ll a[105][105];
	void juzhen(){
			memset(a,0,sizeof a);//结构体赋值
	}
       void unt()//创建单位矩阵
	{
		for(ll i=1;i<=n;i++)
			a[i][i]=1;
	}
}juzhen;
juzhen operator*(const juzhen &d,const juzhen &b)//重载运算符,进行矩阵乘法
{
	juzhen c;
	memset(c.a,0,sizeof c.a);//很重要,明明结构体里已经赋为零了,但这里不加就错
for(ll k=1;k<=n;++k)
		for(ll i=1;i<=n;++i)
			for(ll j=1;j<=n;++j)
				c.a[i][j]=(c.a[i][j]+d.a[i][k]*b.a[k][j]%N)%N;
 
	return c;
}
signed main()
{
	ll k,t;
	cin>>n>>k;
	juzhen a;
	for(ll i=1;i<=n;i++)
	for(ll j=1;j<=n;j++)
	{
		cin>>t;
		a.a[i][j]=t;
	}
	juzhen ans;ans.unt();//建立一个单位矩阵,与任何矩阵相乘,等于矩阵本身,相当于一次幂
	while(k)
	{ 
		if(k&1) ans=ans*a;//与快速幂思想一样,为奇数时结果上*a;但*不能缩写为*=
		a=a*a;k>>=1;
	}
	for(ll i=1;i<=n;putchar('\n'),i++)
	{
		for(ll j=1;j<=n;j++)
			cout<<ans.a[i][j]<<" ";
	}
		return 0;
}

这道题真是废了老大劲,果然不能在没状态时敲,漏洞百出,花了好长时间补bug。我是看了洛谷上的题解,边理解边照猫画虎,也可以去那里看看

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值