矩阵快速幂
矩阵快速幂
和普通快速幂思路差不多
因为矩阵乘法也具有结核性
以下内容需先会快速幂,不会的出门找下面的那篇博客
void ksm(long long a[][1001],long long z){
while(z){
if (z & 1)
{
jc(ans,a);
/* code */
}
jc(a , a);
z >>= 1;
}
}
这是快速幂的模板稍微改动,把乘的那部分换成了一个函数
因为我们也是要实现幂的乘法嘛
这个函数显然不能是
return a * b
因为它要实现的是两个矩阵的乘法
矩阵的乘法公式应该都会吧
A是[n][r] B是[r][m]
c[i][j] = a[i][k] *b[k][j] + a[i][k] * b[k][j] + .... +a[i][r] * b[r][j]
也就是
c[i][j]=∑rk=1a[i][k]∗b[k][j]
(我才不会告诉你们我不会用markdown导致上面这句话打了10多分钟)
两个矩阵相乘的结果就是c矩阵
矩阵乘法的方法应该都会了
我在这里放一种普通的做法
for (long long i = 1; i <= n; ++i)
for (long long j = 1; j <= p; ++j)
for (long long k = 1; k <= m; ++k)
c[i][j] += a[i][k] * b[k][j];
完全按照定义,可以更快,但也快不了多少,一般这样写就可以
聪明的dalao们估计发现了,这就是函数的那一部分
那就加上就好啦
#include <bits/stdc++.h>
using namespace std;
long long a[1001][1001],b[1001][1001];
long long c[1001][1001],ans[1001][1001];
long long n,kd;
long long mo = 1e9 + 7;
void jc(long long a[][1001],long long b[][1001]){//把a和b乘起来
memset(c,0,sizeof c);
for (long long i = 1; i <= n; ++i)
for (long long j = 1; j <= n; ++j)
for (long long k = 1; k <= n; ++k)
c[i][j] += a[i][k] % mo * b[k][j] % mo;
for (long long i = 1; i <= n; ++i)
for (long long j = 1; j <= n; ++j){
a[i][j]=c[i][j] % mo;
}
}
void ksm(long long a[][1001],long long z){
while(z){
if (z & 1)
{
jc(ans,a);//乘出ans,就像ans *= a一样
/* code */
}
jc(a , a);//a *= a
z >>= 1;
}
}
int main()
{
freopen("testdata.in","r",stdin);
freopen("t.out","w",stdout);
cin>>n>>kd;
for (long long i = 1; i <= n; ++i)
{
for (long long j = 1; j <= n; ++j)
{
scanf("%lld",&a[i][j]);
a[i][j] %= mo;
ans[i][j] = a[i][j];
/* code */
}
/* code */
}
ksm(a,kd - 1);
for (long long i = 1; i <= n; ++i){
for (long long j = 1; j <= n; ++j)
cout<<ans[i][j] % mo<<' ';
cout<<endl;
}
return 0;
}
这其实也是洛谷p3390 矩阵快速幂的代码
由于题目要求
%了
109+7
然后开了long long,除了这些就没什么区别了
作者: liuzitong
出处:http://www.cnblogs.com/lztzs/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步