zoukankan      html  css  js  c++  java
  • 题解 P4783 【【模板】矩阵求逆】

    题目大意

    求一个N×N的矩阵的逆矩阵。答案对10^9+7取模。N<=400


    前置知识

    矩阵的初等变换

    矩阵的逆定义为 A*B=E(E为单位矩阵)此时B为A的逆 


    思路

    如果矩阵有逆

    那么这个矩阵经过一系列初等变化之后可以变为E

    设一系列初等变化分别为p1,p2,p3...px

    显然可得A*p1*p2*p3*...*px=E

    所以B=p1*p2*p3*...*px

    这样的话就很好做了

    我们利用高斯消元来让A逐渐变为单位矩阵

    设B初始为E

    B也跟着A同步变换

    那么到A变为单位矩阵时 B也就是p1*p2*p3*...*px的值了

    矩阵无逆的情况显然是高斯消元无法再消(a[1][i]-a[n][i]都为0时)特判输出就行哩


    代码

    #include<bits/stdc++.h> 
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    } 
    const ll N=410,p=1e9+7;
    ll n; 
    struct xin{
        ll a[N][N];
        //inline int* operator [](int x){return a[x];} //  b的话直接调用b[][] 
        inline void swap(int x,int y){for(int i=1;i<=n;i++) swap(a[x][i],a[y][i]);}
        inline void mul(int x,int k){for(int i=1;i<=n;i++) a[x][i]=(a[x][i]*k%p+p)%p;}//a[x]=k*a[y];
        inline void add(int x,int y,int k){for(int i=1;i<=n;i++) a[x][i]=((a[x][i]+a[y][i]*k)%p+p)%p;}// a[x]加k*a[y] 
        inline void prt()
        {
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++) printf("%lld ",a[i][j]);
                printf("
    ");
            }
        }
    }a,b;
    inline ll ksm(ll a,ll b)
    {
        ll ans=1;
        while(b)
        {
            if(b&1) ans=(ans*a)%p;
            a=(a*a)%p;
            b>>=1;
        }
        return ans;
    }
    void gaosi()
    {
        for(int i=1;i<=n;i++)
        {
            if(!a.a[i][i]) for(int j=i+1;j<=n;j++) if(a.a[j][i])
            {
                a.swap(i,j);b.swap(i,j);
                break;
            }
            if(!a.a[i][i]){printf("No Solution
    ");exit(0);} 
            b.mul(i,ksm(a.a[i][i],p-2));a.mul(i,ksm(a.a[i][i],p-2));//把所有项除a[i][i] 变成a[i][i]变成1 
            for(int j=1;j<=n;j++)
            {
                if(i==j) continue; 
                b.add(j,i,-a.a[j][i]);a.add(j,i,-a.a[j][i]);//消去  b要放前面因为a放前面会被修改 
            }
        }
    }
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
          a.a[i][j]=read();
        for(int i=1;i<=n;i++) b.a[i][i]=1;
        gaosi();
        b.prt();
        return 0;
    }
  • 相关阅读:
    搭建CDH的yum本地源
    搭建一个离线yum源
    VMware主机 几次断电后,挂载的磁盘报错了,系统无法启动
    vm workstation15 迁移至ESXi6.7步奏
    ESXi6.7在 ASUS PRIME B360-PLUS 主板上安装报错
    php常用函数
    PHP函数
    php语句
    TSQL语句练习题
    php的基础
  • 原文地址:https://www.cnblogs.com/1436177712qqcom/p/10467470.html
Copyright © 2011-2022 走看看