topic background
Matrix fast exponentiation
Topic description
Given an n*n matrix A, find A^k
Input and output format
Input format:
The first row, n,k
Rows 2 to n+1, each row has n numbers, and the jth number in row i+1 represents the element in row i and column j of the matrix
Output format:
output A^k
A total of n rows, each row has n numbers, the i-th row and the j-th number represent the elements of the i-th row and the j-th column of the matrix, each element modulo 10^9+7
illustrate
n<=100, k<=10^12, |Matrix Elements|<=1000 Algorithm: Matrix Fast Power
Ideas:
A template matrix fast exponentiation
First understand what is matrix multiplication
For example, the f[][] matrix is multiplied by j[][], and the answer matrix is ans[2][2]
则ans[1][1]=f[1][1]*j[1][1]+f[1][2]*j[2][1]+.....+f[1 ][k]*j[k][1]
ans[1][2]=f[1][1]*j[1][2]+f[1][2]*j[2][2]+.....+f[1] [k]*j[k][2]
。
。
。
That is to say, each element of ans[a][b]=Σf[a][1~k] is multiplied by each element of j[1~k][b]
As shown in the figure:
Half of the mission is over, but it's still short of fast power
I believe you are not naive enough to scan o(k) once in the case of k=10^12
How to do? ?
Quick power comes to the rescue
For details about fast power, please refer to my other blog
time down to o(logn);
pass
Code:
#include<iostream> #include<cstdio> #define rii register int i #define row register int j #define rik register int k using namespace std; long long x[105][105],zcq[105][105],ls[105][105],n,k,mod=1e9+7; void cf2() { long long ans=0; for(rii=1;i<=n;i++) { for(rij=1;j<=n;j++) { ls[i][j]=zcq[i][j]; } } for(rii=1;i<=n;i++) { for(rij=1;j<=n;j++) { for(rik=1;k<=n;k++) { ans + = (x [i] [k] * ls [k] [j])% mod; ans=ans%mod; } zcq[i][j]=ans%mod; years=0; } } } void cf1() { long long ans=0; for(rii=1;i<=n;i++) { for(rij=1;j<=n;j++) { ls[i][j]=x[i][j]; } } for(rii=1;i<=n;i++) { for(rij=1;j<=n;j++) { for(rik=1;k<=n;k++) { ans+=(ls[i][k]*ls[k][j])%mod; ans=ans%mod; } x [i] [j] = ans% mod; years=0; } } } void ksm(long long k) { if(k==0) { return; } if(k%2==0) { cf1(); ksm (k / 2); return; } else { cf2(); ksm (k-1); return; } } intmain() { scanf("%lld%lld",&n,&k); for(rii=1;i<=n;i++) { for(rij=1;j<=n;j++) { scanf("%d",&x[i][j]); zcq[i][j]=x[i][j]; } } ksm (k-1); for(rii=1;i<=n;i++) { for(rij=1;j<=n;j++) { printf("%ld ",zcq[i][j]); } printf("\n"); } }