码迷,mamicode.com
首页 > 其他好文 > 详细

(模板)求逆矩阵luoguP4783

时间:2019-10-30 14:01:53      阅读:84      评论:0      收藏:0      [点我收藏+]

标签:bsp   cst   ace   can   name   scanf   交换   str   高斯   

题目链接:https://www.luogu.org/problem/P4783

题意:求矩阵的逆。

思路:高斯消元法求矩阵的逆,n为400,卡常,我是开了O2优化才AC的。。

AC代码:

#include<cstdio>
#include<cctype>
#include<algorithm>
#define R register int
using namespace std;

const int maxn=405;
const int MOD=1e9+7;
int n;

struct Matrix{
    int m[maxn][maxn];
    void SWAP(int x,int y){   //交换两行
        for(R i=1;i<=n;++i)
            swap(m[x][i],m[y][i]);
    }
    void MUL(int x,int k){    //对一行乘上k
        for(R i=1;i<=n;++i)
            m[x][i]=(1LL*m[x][i]*k%MOD+MOD)%MOD;
    }
    void MULADD(int x,int y,int k){ //将第y行乘上k加到第x行上去
        for(R i=1;i<=n;++i)
            m[x][i]=((m[x][i]+1LL*m[y][i]*k%MOD)%MOD+MOD)%MOD;
    }
}A,B;

int qpow(int a,int b){   //求逆元
    int ret=1;
    while(b){
        if(b&1) ret=1LL*ret*a%MOD;
        a=1LL*a*a%MOD;
        b>>=1;
    }
    return ret;
}

void Invmatrix(){
    for(R i=1;i<=n;++i){
        if(!A.m[i][i]){
            for(R j=i+1;j<=n;++j)
                if(A.m[j][i]){
                    B.SWAP(i,j);
                    A.SWAP(i,j);
                    break;
                }
        }
        if(!A.m[i][i]){  //没有逆矩阵
            puts("No Solution");
            return;
        }
        int tmp=qpow(A.m[i][i],MOD-2);
        B.MUL(i,tmp);
        A.MUL(i,tmp);    //系数化为1
        for(R j=i+1;j<=n;++j){  //消元
            tmp=-A.m[j][i];
            B.MULADD(j,i,tmp);
            A.MULADD(j,i,tmp);
        }
    }    
    for(R i=n-1;i>=1;--i)  //回带
        for(R j=i+1;j<=n;++j){
            int tmp=-A.m[i][j];
            B.MULADD(i,j,tmp);
            A.MULADD(i,j,tmp);
        }
    for(R i=1;i<=n;++i){
        for(R j=1;j<=n;++j){
            printf("%d",B.m[i][j]);
            if(j!=n) printf(" ");
        }
        printf("\n");
    }
}

int main(){
    scanf("%d",&n);
    for(R i=1;i<=n;++i)
        for(R j=1;j<=n;++j)
            scanf("%d",&A.m[i][j]);
    for(R i=1;i<=n;++i){
        for(R j=1;j<=n;++j)
            B.m[i][j]=0;
        B.m[i][i]=1;
    }
    Invmatrix();
    return 0;
}

 

(模板)求逆矩阵luoguP4783

标签:bsp   cst   ace   can   name   scanf   交换   str   高斯   

原文地址:https://www.cnblogs.com/FrankChen831X/p/11764185.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!