众所周知,快速幂很常用,矩阵快速幂同样常用(就是个模板废话那么多干嘛)
废话不多说,开始正片:
矩阵快速幂,就是算一个矩阵的k次方,它和一个数的k次方计算起来是类似的,我们不妨先写出来数的快速幂的代码:
int ksm(int a,int r) {int ans=1; while(r) {if(r&1)ans=ans*a; a=a*a; r/=2; } return ans; }
矩阵快速幂也是同样的,不过要重载一下运算符,将a与ans的乘法变成矩阵乘
矩阵乘:有两个分别为m*k和k*n的矩阵可以做乘法,结果矩阵为m*n的矩阵,拿二阶乘二阶举个例子(原谅我不会markdown)
| a11 a12 | * |b11 b12| = | a11*b11+a12*b21 a11*b12+a12*b22|
| a21 a22 | |b21 b22| | a21*b11+a22*b21 a21*b12+a22*b22|
嗯就是这样
完整代码如下
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; int n,m,p; struct jz //结构体比较方便,如果硬开几个数组也行 {int a[101][101]; }jlgz,ans; jz operator *(jz a,jz b)//矩阵乘 { jz c; for(int i=0;i<=1;i++) {for(int j=0;j<=1;j++) {c.a[i][j]=0; for(int k=0;k<=1;k++) c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%p; } } return c; } int main() { scanf("%d%d%d",&n,&m,&p);//求n阶矩阵的m次方mod p for(int i=0;i<n;i++) { for(int j=0;j<n;j++) scanf("%d",&jlgz.a[i][j]); } int r=m; for(int i=0;i<n;i++) { ans.a[i][i]=1; } while(r) //快速幂代码 {if(r&1)ans=ans*jlgz; jlgz=jlgz*jlgz; r/=2; } for(int i=0;i<n;i++) {for(int j=0;j<n;j++) cout<<ans.a[i][j]<<" "; cout<<endl; } }
完毕~~~~~