矩阵快速幂
矩阵快速幂
1.矩阵乘法:
对于n*k的矩阵A,k*m的矩阵B,相乘的得到的矩阵C为:

我们可以发现,对于矩阵A,B,只有当A的列等于B的行时,两个矩阵才能相乘。
Code:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=50; 4 int a[N][N],b[N][N],c[N][N]; 5 int n,k,m; 6 int main(){ 7 cin>>n>>k>>m; 8 for(int i=1;i<=n;i++){ 9 for(int j=1;j<=k;j++){ 10 cin>>a[i][j]; 11 } 12 } 13 for(int i=1;i<=k;i++){ 14 for(int j=1;j<=m;j++){ 15 cin>>b[i][j]; 16 } 17 } 18 for(int i=1;i<=n;i++){ 19 for(int j=1;j<=m;j++){ 20 for(int r=1;r<=k;r++){ 21 c[i][j]+=a[i][r]*b[r][j]; 22 } 23 } 24 } 25 for(int i=1;i<=n;i++){ 26 for(int j=1;j<=m;j++){ 27 cout<<c[i][j]<<" "; 28 } 29 cout<<endl; 30 } 31 }
2.矩阵快速幂
在学习矩阵乘法后,我们便可以开始学习矩阵快速幂了。
老规矩,直接上例题:
计算斐波那契数列第n项的后四位(n<=1e9)。
好家伙,这不递推板题嘛!~
仔细点,n<=1e9!
对于如此之大的数据规模,我们只能用O(logn)或O(√n)的算法来实现。
那O(logn)的快速幂算法就十分合适了。
我们先列出递推方程式:

其中,1 1 1 0这个矩阵可以通过方程求得。

于是,我们只需要类比普通的快速幂计算1 1 1 0这个矩阵即可。
附上矩阵快速幂的模板:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define int long long 4 const int N=110; 5 const int P=1e9+7; 6 int k,n; 7 int ans[N][N],x[N][N],dx[N][N]; 8 9 void pow1(){ 10 for(int i=1;i<=n;i++){ 11 for(int j=1;j<=n;j++){ 12 dx[i][j]=ans[i][j]; 13 ans[i][j]=0; 14 } 15 } 16 for(int i=1;i<=n;i++){ 17 for(int j=1;j<=n;j++){ 18 for(int k=1;k<=n;k++){ 19 ans[i][j]=(ans[i][j]+dx[i][k]*x[k][j]%P)%P; 20 } 21 } 22 } 23 } 24 25 void pow2(){ 26 for(int i=1;i<=n;i++){ 27 for(int j=1;j<=n;j++){ 28 dx[i][j]=x[i][j]; 29 x[i][j]=0; 30 } 31 } 32 for(int i=1;i<=n;i++){ 33 for(int j=1;j<=n;j++){ 34 for(int k=1;k<=n;k++){ 35 x[i][j]=(x[i][j]+dx[i][k]*dx[k][j]%P)%P; 36 } 37 } 38 } 39 } 40 41 signed main(){ 42 cin>>n>>k; 43 for(int i=1;i<=n;i++){ 44 for(int j=1;j<=n;j++){ 45 cin>>ans[i][j]; 46 x[i][j]=ans[i][j]; 47 } 48 } 49 k--; 50 while(k){ 51 if(k%2==1) pow1(); 52 pow2(); 53 k/=2; 54 } 55 for(int i=1;i<=n;i++){ 56 for(int j=1;j<=n;j++){ 57 cout<<ans[i][j]<<" "; 58 } 59 cout<<endl; 60 } 61 return 0; 62 }

浙公网安备 33010602011771号