zoukankan      html  css  js  c++  java
  • Luogu4783 【模板】矩阵求逆(高斯消元)

      对矩阵进行高斯消元直至消为单位矩阵,并在另一个单位矩阵上对其做同样的操作即可。

      模意义下的高斯消元可以直接计算系数来避免整行的辗转相除。

      还不知道有什么用。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define P 1000000007
    #define N 410
    int n,a[N][N],b[N][N];
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int ksm(int a,int k)
    {
        if (k==0) return 1;
        int tmp=ksm(a,k>>1);
        if (k&1) return 1ll*tmp*tmp%P*a%P;
        else return 1ll*tmp*tmp%P;
    }
    int inv(int a){return ksm(a,P-2);}
    void gauss()
    {
        for (int i=1;i<n;i++)
        {
            if (!a[i][i])
            for (int j=i+1;j<=n;j++)
            if (a[j][i]) {swap(a[i],a[j]),swap(b[i],b[j]);break;}
            for (int j=i+1;j<=n;j++)
            if (a[j][i])
            {
                int x=a[j][i]/gcd(a[i][i],a[j][i]),y=a[i][i]/gcd(a[i][i],a[j][i]);
                for (int k=1;k<=n;k++)
                a[j][k]=(1ll*a[j][k]*y%P-1ll*a[i][k]*x%P+P)%P,
                b[j][k]=(1ll*b[j][k]*y%P-1ll*b[i][k]*x%P+P)%P;
            }
        }
        if (a[n][n])
        {
            for (int i=1;i<=n;i++)
            b[n][i]=1ll*b[n][i]*inv(a[n][n])%P;
            a[n][n]=1;
        }
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read();
        for (int i=1;i<=n;i++)
            for (int j=1;j<=n;j++)
            a[i][j]=read(),b[i][j]=(i==j);
        gauss();
        for (int i=1;i<=n;i++) if (a[i][i]==0) {cout<<"No Solution";return 0;}
        for (int i=n;i>1;i--)
            for (int j=i-1;j>=1;j--)
            if (a[j][i])
            {
                int x=a[j][i]/gcd(a[i][i],a[j][i]),y=a[i][i]/gcd(a[i][i],a[j][i]);
                for (int k=1;k<=n;k++)
                a[j][k]=(1ll*a[j][k]*y%P-1ll*a[i][k]*x%P+P)%P,
                b[j][k]=(1ll*b[j][k]*y%P-1ll*b[i][k]*x%P+P)%P;
            }
        for (int i=1;i<=n;i++)
            for (int j=1;j<=n;j++)
            b[i][j]=1ll*b[i][j]*inv(a[i][i])%P;
        for (int i=1;i<=n;i++)
        {
            for (int j=1;j<=n;j++)
            printf("%d ",b[i][j]);
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    学习笔记——Maven实战(九)打包的技巧
    学习笔记——Maven实战(八)常用Maven插件介绍(下)
    学习笔记——Maven实战(七)常用Maven插件介绍(上)
    学习笔记——Maven实战(六)Gradle,构建工具的未来?
    学习笔记——Maven实战(五)自动化Web应用集成测试
    在Google的GKE上创建支持Internal Load Balancer的Service
    Bash命令查找本机公网IP
    Google Cloud IAM中添加自定义域名
    Debian上启用Apache2服务
    Google Cloud VM上在线扩硬盘
  • 原文地址:https://www.cnblogs.com/Gloid/p/9615445.html
Copyright © 2011-2022 走看看