高斯消元矩阵的逆+行列式的值

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL;
#define Mod 1000000007
const int maxn=200+5;
int n;//n阶方阵
LL A[maxn][maxn],Inv[maxn][maxn];//A为已知n阶方阵,Inv为矩阵A^(-1)
LL detA;//|A|w为行列式的值
//快速幂
LL pow_mod(LL x,LL n)
{
   LL res=1;
   while(n>0)
   {
       if(n&1) res=res*x%Mod;
       x=x*x%Mod;
       n>>=1;
   }
   return res;
}

void Gauss_Eli()
{

    detA=1;//初始化
    //初始化n阶单位矩阵
    for (int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
        {
            if(i==j)
            {
                Inv[i][j]=1;
            }
            else
            {
                Inv[i][j]=0;
            }
        }
    }
    for(int i=1; i<=n; i++)
    {
        int tmp;
        for(int j=i; j<=n; j++)
        {
            if(A[j][i]) tmp=j;
        }
        if(tmp!=i)
        {
            detA*=-1;////行列式交换两行取负
        }
        //交换两行,矩阵的逆也做对应的变换
        for(int j=1; j<=n; j++)
        {
            swap(A[tmp][j],A[i][j]);
            swap(Inv[tmp][j],Inv[i][j]);
        }
        detA=(detA*A[i][i]%Mod+Mod)%Mod;
        LL t=pow_mod(A[i][i],Mod-2);//求逆元

        for(int j=1; j<=n; j++)
        {
            A[i][j]=A[i][j]*t%Mod;
            Inv[i][j]=Inv[i][j]*t%Mod;
        }
        for(int r=1; r<=n; r++)
        {
            if(r==i) continue;
            LL mult=A[r][i];
            for(int c=1; c<=n; c++)
            {
                A[r][c]=(A[r][c]-A[i][c]*mult%Mod+Mod)%Mod;
                Inv[r][c]=(Inv[r][c]-Inv[i][c]*mult%Mod+Mod)%Mod;
            }
        }
    }

//    for(int i=1;i<=n;i++)
//    {
//        for(int j=1;j<=n;j++)
//        {
//            printf("%d ",Inv[i][j]);
//        }
//        printf("\n");
//    }
//    printf("detA=%d\n",detA);

}

int main()
{
    while(~scanf("%d",&n))
    {

        for(int i=1; i<=n; i++)
            A[1][i]=1;
        for(int i=2; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
            {
                scanf("%I64d",&A[i][j]);
            }
        }

        Gauss_Eli();
        for(int i=1; i<=n; i++)
        {
            if(i%2==0) Inv[i][1]=(Mod-Inv[i][1])%Mod;
            if(i<n)
                printf("%I64d ",(Inv[i][1]*detA + Mod)%Mod);
            else
                printf("%I64d\n",(Inv[i][1]*detA + Mod)%Mod);
        }

    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值