【模板】【代数】矩阵乘法和矩阵快速幂
2017-08-16 10:44
381 查看
矩阵乘法
定义
设A为m*p的矩阵,B为p*n的矩阵,那么称m*n的矩阵C为矩阵A与B的乘积,记作C=AB,其中矩阵C中的第 i 行第 j 列元素可以表示为:(AB)ij=∑k=1paikbkj=ai1b1j+ai2b2j+⋯+aipbpj注意事项
1.当矩阵 A 的列数等于矩阵 B 的行数时, A 与 B 可以相乘。2.矩阵 C 的行数等于矩阵 A 的行数, C 的列数等于 B 的列数。
3.乘积 C 的第 m 行第 n 列的元素等于矩阵 A 的第 m 行的元素与矩阵 B 的第 n 列对应元素乘积之和。
基本性质
1.乘法结合律: (AB)C=A(BC)2.乘法左分配律:(A+B)C=AC+BC
3.乘法右分配律:C(A+B)=CA+CB
4.对数乘的结合性k(AB)=(kA)B=A(kB)
5.矩阵乘法一般不满足交换律
代码
struct matrix{ LL z[mxl][mxr]; int m,n;//矩阵的行数和列数 }; matrix mul(matrix x,matrix y)//矩阵乘法 { matrix t; t.m=x.m;//新矩阵的行数等于第一个矩阵的行数 t.n=y.n;//新矩阵的列数等于第二个矩阵的列数 memset(t.z,0,sizeof(t.z)); for(int i=1;i<=x.m;i++) for(int j=1;j<=y.n;j++) for(int k=1;k<=y.m;k++) t.z[i][j]+=x.z[i][k]*y.z[k][j]; return t; }
时间复杂度O(n3)
矩阵快速幂
与数的快速幂原理相同,只不过运算对象换成了矩阵。数的快速幂请看http://blog.csdn.net/george__yu/article/details/77259517
矩阵快速幂能在O(n3log2k)的时间内算出Ak,其中A是一个矩阵。
代码
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <cmath> using namespace std; typedef long long LL; const int mxl=103,mxr=103; struct matrix{ LL z[mxl][mxr]; int m,n;//矩阵的行数和列数 }res,ori;//res:单位矩阵 ,ori:输入的矩阵 LL p=1000000007,k; void init() { scanf("%d%d%lld",&ori.m,&ori.n,&k);//输入指数,行数,列数 res.m=ori.m;res.n=ori.n;//初始化单位矩阵的行数和列数 for(int i=0;i<=res.m+1;i++) res.z[i][i]=1;//初始化单位矩阵 for(int i=1;i<=ori.m;i++)//输入矩阵 for(int j=1;j<=ori.n;j++) scanf("%lld",&ori.z[i][j]); } matrix mul(matrix x,matrix y)//矩阵乘法 { matrix t; t.m=x.m;//新矩阵的行数等于第一个矩阵的行数 t.n=y.n;//新矩阵的列数等于第二个矩阵的列数 memset(t.z,0,sizeof(t.z)); for(int i=1;i<=x.m;i++) for(int j=1;j<=x.n;j++) { t.z[i][j]=0; for(int k=1;k<=y.n;k++) t.z[i][j]=(t.z[i][j]+x.z[i][k]*y.z[k][j])%p; } return t; } void MatrixModpow(LL k)//矩阵快速幂 { while(k) { if(k&1) res=mul(res,ori); ori=mul(ori,ori); k>>=1; } } void print(matrix x)//打印矩阵 { for(int i=1;i<=x.m;i++) { for(int j=1;j<=x.n;j++) printf("%lld ",x.z[i][j]); printf("\n"); } } int main() { init(); MatrixModpow(k); print(res); return 0; }
再补一个代码
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cstdlib> #include <cmath> using namespace std; typedef long long LL; const int mxl = 103,mxr = 103; const LL mod = 1e9+7; struct Matrix{ LL l,r; LL num[mxl][mxr]; Matrix() {memset(num,0,sizeof(num)); l=0; r=0;} Matrix operator * (const Matrix &b) const { if(r!=b.l) return *this; Matrix c; c.l=l;c.r=b.l; for(int i=1;i<=l;i++) for(int j=1;j<=b.r;j++) for(int k=1;k<=r;k++) c.num[i][j]=(c.num[i][j]+(num[i][k]*b.num[k][j])%mod)%mod; return c; } Matrix ModPow(LL b) { Matrix res,a; a=*this; res.l=res.r=a.l; for(int i=1;i<=res.l;i++) res.num[i][i]=1; while(b) { if(b&1) res=res*a; a=a*a; b>>=1; } return res; } inline void read(int ll,int rr) { l=ll;r=rr; for(int i=1;i<=l;i++) for(int j=1;j<=r;j++) scanf("%lld",&num[i][j]); } inline void write() { for(int i=1;i<=l;i++) { for(int j=1;j<=r;j++) printf("%lld ",num[i][j]); printf("\n"); } } }; LL n,k; Matrix a,b; int main() { scanf("%lld%lld",&n,&k); a.read(n,n); a.ModPow(k).write(); return 0; }
用途:优化一类线性递推问题。
具体请看我的这一篇博客:http://blog.csdn.net/george__yu/article/details/77249237相关文章推荐
- 【图灵杯 F】一道简单的递推题(矩阵快速幂,乘法模板)
- 矩阵乘法快速幂模板
- 快速幂模板 -->加法快速幂+乘法快速幂+矩阵快速幂
- 那啥,,矩阵乘法,矩阵快速幂模板
- Luogu 3390 【模板】矩阵快速幂 (矩阵乘法,快速幂)
- 【矩阵乘法】【快速幂】【递推】斐波那契数列&&矩乘优化递推模板
- ACM 矩阵乘法模板(T_T)+快速幂
- 矩阵乘法以及矩阵快速幂模板
- hdu 5411 多校——矩阵快速幂模板
- codevs1281 矩阵乘法 快速幂 !!!手写乘法取模!!! 练习struct的构造函数和成员函数
- 矩阵快速幂的写法(模板)
- HDU1575:Tr A(矩阵快速幂模板题)
- 矩阵快速幂和矩阵的乘法模板
- poj 3070 Fibonacci(矩阵乘法快速幂)
- 51nod1113(矩阵快速幂模板)
- 线性代数:矩阵乘法和逆矩阵
- Fibonacci数列(矩阵乘法快速幂)
- hdu 1575 Tr A(矩阵乘法快速求幂)
- 模板:(数学:矩阵快速幂)
- BZOJ1009 单模板自动机 矩阵快速幂优化DP