上一篇写了快速幂[模板] ,这篇是有关拓展,矩阵快速幂=矩阵乘法+快速幂。下面是洛谷里的一道模板题,写之前要了解矩阵乘法。关于重载运算符,这里用不用都行。
【模板】矩阵快速幂
题目描述
给定 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 1≤n≤100, 0 ≤ k ≤ 1 0 12 0 \le k \le 10^{12} 0≤k≤1012, ∣ A i , j ∣ ≤ 1000 |A_{i,j}| \le 1000 ∣Ai,j∣≤1000。
代码
#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。我是看了洛谷上的题解,边理解边照猫画虎,也可以去那里看看
&spm=1001.2101.3001.5002&articleId=138541279&d=1&t=3&u=d12326aca14844268520bc01b7ade490)
371

被折叠的 条评论
为什么被折叠?



