【线性代数】
【线性代数】
【矩阵封装】
矩阵加法/乘法
//矩阵加乘封装:1-based
//如不用取模:mod请用超大质数100000000000000003
const int MAX_SIZE=200; // 最大矩阵大小
struct Matrix{
int rows,cols;
i64 M[MAX_SIZE+5][MAX_SIZE+5];
Matrix(int r=0,int c=0):rows(r),cols(c){
clear();
}
void clear(){
memset(M,0,sizeof(M));
}
//重置为单位矩阵
void reset(){
clear();
for(int i=1;i<=min(rows,cols);i++){
M[i][i]=1;
}
}
//矩阵乘法: nxm mxp -> nxp
Matrix friend operator*(const Matrix &A,const Matrix &B){
if (A.cols!=B.rows){
return Matrix(0,0); //不合法返回空矩阵
}
Matrix Ans(A.rows,B.cols);
Ans.clear();
for(int i=1;i<=A.rows;i++){
for(int j=1;j<=B.cols;j++){
for(int k=1;k<=A.cols;k++){
Ans.M[i][j]=(Ans.M[i][j]+A.M[i][k]*B.M[k][j])%mod;
}
}
}
return Ans;
}
//矩阵加法
Matrix friend operator+(const Matrix &A, const Matrix &B){
if(A.rows!=B.rows || A.cols!=B.cols){
return Matrix(0, 0); //不合法返回空矩阵
}
Matrix Ans(A.rows,A.cols);
Ans.clear();
for(int i=1;i<=A.rows;i++){
for(int j=1;j<=A.cols;j++){
Ans.M[i][j]=(A.M[i][j]+B.M[i][j])%mod;
}
}
return Ans;
}
};
示例
int n,m,p;
void solve(){
cin>>n>>m;
Matrix s1(n,m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>s1.M[i][j];
}
}
cin>>p;
Matrix s2(m,p);
for(int i=1;i<=m;i++){
for(int j=1;j<=p;j++){
cin>>s2.M[i][j];
}
}
Matrix ans=s1*s2;
for(int i=1;i<=n;i++){
for(int j=1;j<=p;j++){
cout<<ans.M[i][j]<<" ";
}
cout<<endl;
}
}
矩阵求逆
//矩阵求逆:仅适用于方阵
bool ok=1;
Matrix getinv(Matrix a){
// 检查是否为方阵
if(a.rows!=a.cols){
puts("-1");
ok=0;
return Matrix(0,0);
}
int n=a.rows;
int m=2*n;
for(int i=1;i<=n;i++){
a.M[i][i+n]=1;
}
for(int i=1;i<=n;i++){
int pos=i;
for(int j=i+1;j<=n;j++){
if(abs(a.M[j][i])>abs(a.M[pos][i])){
pos=j;
}
}
if(i!=pos){
swap(a.M[i],a.M[pos]);
}
if(!a.M[i][i]){
puts("-1");
ok=0;
return Matrix(0,0);
}
i64 inv=qmi(a.M[i][i],mod-2LL,mod);
for(int j=1;j<=n;j++){
if(j!=i){
i64 mul=a.M[j][i]*inv%mod;
for(int k=i;k<=m;k++){
a.M[j][k]=((a.M[j][k]-a.M[i][k]*mul)%mod+mod)%mod;
}
}
}
for(int j=1;j<=m;j++){
a.M[i][j]=a.M[i][j]*inv%mod;
}
}
Matrix res(n,n);
res.clear();
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
res.M[i][j]=a.M[i][n+j];
}
}
return res;
}
矩阵快速幂
不需要使用Matrix封装
const int N = 110, mod = 1e9 + 7;
i64 n, k, a[N][N], b[N][N], t[N][N];
void matrixQp(i64 y){
while (y){
if (y & 1){
memset(t, 0, sizeof t);
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ )
for (int k = 1; k <= n; k ++ )
t[i][j] = ( t[i][j] + (a[i][k] * b[k][j]) % mod ) % mod;
memcpy(b, t, sizeof t);
}
y >>= 1;
memset(t, 0, sizeof t);
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ )
for (int k = 1; k <= n; k ++ )
t[i][j] = ( t[i][j] + (a[i][k] * a[k][j]) % mod ) % mod;
memcpy(a, t, sizeof t);
}
}
int main(){
cin >> n >> k;
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ ){
cin >> b[i][j];
a[i][j] = b[i][j];
}
matrixQp(k - 1);//注意这里是k-1
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ )
cout << b[i][j] << " \n"[j == n];
return 0;
}