矩阵快速幂
学快速幂时,做到了矩阵快速幂,就学习了一下矩阵乘法,今天又碰到了一个关于矩阵乘法的问题,就顺便整理复习一下。
快速幂
快速幂顾名思义就是让乘方运算更加快速的算法,n^x这样的乘方运算本来是要n*n*n*……*n(共x个n)这样一个一个运算,但快速幂的思想是将n分成2的多次方和,如2^34=2^32*2^2,呈现方式是通过二分,如2^34=(2^17)^2=(2^16*2)^2=((((2^2)^2)^2)^2*2)^2
long long ksm(int n,int x){ if(x==0) return 1; long long ans=ksm(n,x/2); ans*=ans; if(x%2==1) ans*=n; return ans; }
矩阵乘法
矩阵乘法就是一个m*n的矩阵A乘一个n*p的矩阵B得到一个m*p的矩阵C
这样看矩阵乘法只有结合律,没有交换律
C[i][j]=a[i][1]*b[1][j]+a[i][2]*b[2][j]+……+a[i][n]*b[n][j]
例如:A=|1 2 3|
|4 5 6|
B=|1 5|
|3 7|
|2 4|
C=A*B=|1*1+2*3+3*2 1*5+2*7+3*4|=|13 31|
|1*4+3*5+2*6 4*5+5*7+6*4| |31 79|
for(int i=1;i<=m;i++){ for(int j=1;j<=p;j++){ for(int k=1;k<=n;k++){ c[i][j]+=a[i][k]*b[k][j]; } } }
矩阵快速幂
矩阵快速幂就是矩阵乘法和快速幂的结合
int ans[101][101]; void jzksm(int a[101][101],int n){ if(n==1){ for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ ans[i][j]=a[i][j]; } } return ; } jzksm(a,n/2); int t[101][101]; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ for(int k=1;k<=n;k++){ t[i][j]+=ans[i][k]*ans[k][j]; } } } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ ans[i][j]=t[i][j]; t[i][j]=0; } } if(n%2==1){ for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ for(int k=1;k<=n;k++){ t[i][j]+=ans[i][k]*a[k][j]; } } } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ ans[i][j]=t[i][j]; t[i][j]=0; } } } }