【洛谷P3390】矩阵快速幂
矩阵快速幂
矩阵乘法:
A[n*m]*B[m*k]=C[n*k];
C[i][j]=sum(A[i][1~n]+B[1~n][j])
为了便于赋值和定义,我们定义一个结构体储存矩阵:
struct Matrix{ long long m[100][100]; };
X*Y:
1 Matrix cheng(Matrix X,Matrix Y) 2 { 3 Matrix C; 4 for(long long i=1;i<=n;i++) 5 for(long long j=1;j<=n;j++) 6 { 7 C.m[i][j]=0; 8 for(long long l=1;l<=n;l++) 9 C.m[i][j]=(C.m[i][j]+X.m[i][l]*Y.m[l][j])%MOD; 10 } 11 return C; 12 }
快速幂:
把k转化为二进制,
如k=10(10)=1010(2);
a^10=a^(2^3) * a^(2^1)=(a^8)*(a^2)
代码:
Matrix qsort(Matrix X,long long p) { Matrix S=E; while(p) { if(p&1) S=cheng(S,X); X=cheng(X,X); p>>=1; } return S; }
其中E是一个矩阵,相当于数字1,任何一个矩阵A*E=A。
当n=10时,E等于
1,0,0,0,0,0,0,0,0,0
0,1,0,0,0,0,0,0,0,0
0,0,1,0,0,0,0,0,0,0
0,0,0,1,0,0,0,0,0,0
0,0,0,0,1,0,0,0,0,0
0,0,0,0,0,1,0,0,0,0
0,0,0,0,0,0,1,0,0,0
0,0,0,0,0,0,0,1,0,0
0,0,0,0,0,0,0,0,1,0
0,0,0,0,0,0,0,0,0,1
生成矩阵E:
for(long long i=1;i<=n;i++) E.m[i][i]=1;
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; long long n,k; const long long MOD=1000000007; struct Matrix{ long long m[100][100]; }; Matrix A,E,ANS; Matrix cheng(Matrix X,Matrix Y) { Matrix C; for(long long i=1;i<=n;i++) for(long long j=1;j<=n;j++) { C.m[i][j]=0; for(long long l=1;l<=n;l++) C.m[i][j]=(C.m[i][j]+(X.m[i][l]*Y.m[l][j]))%MOD; } return C; } Matrix qsort(Matrix X,long long p) { Matrix S=E; while(p) { if(p&1) S=cheng(S,X); X=cheng(X,X); p>>=1; } return S; } int main() { scanf("%lld%lld",&n,&k); for(long long i=1;i<=n;i++) E.m[i][i]=1; for(long long i=1;i<=n;i++) for(long long j=1;j<=n;j++) scanf("%lld",&A.m[i][j]); ANS=qsort(A,k); for(long long i=1;i<=n;i++) { for(long long j=1;j<=n;j++) printf("%lld ",ANS.m[i][j]); puts(""); } return 0; }