求逆矩阵【模板】

题目

P4783

求一个 $N \times N$ 的矩阵的逆矩阵。答案对 $10^9+7$ 取模。若不可逆,输出 "No Solution"。

分析

由线性代数的知识,求矩阵A的逆矩阵时,

只需在A的右边补充一个单位矩阵,进行初等行变换,当A变成单位矩阵时,右边的就是A的逆矩阵。

简单的证明:$AE\rightarrow E{A}‘$

代码

//来自https://blog.csdn.net/qq_43653202/article/details/99976316

#include<iostream>
#include<cstdio>
#include<cmath>
#define re register
#define il inline
#define ll long long
using namespace std;

il ll read(){
    ll s=0,f=0;char c=getchar();
    while(c<‘0‘||c>‘9‘) f=(c==‘-‘),c=getchar();
    while(c>=‘0‘&&c<=‘9‘) s=(s<<3)+(s<<1)+(c^‘0‘),c=getchar();
    return f?-s:s;
}

const int N=405,mod=1e9+7;
int n;
ll a[N][N<<1];
il ll qpow(ll x,ll k){
    ll ans=1;
    while(k){
        if(k&1) ans=ans*x%mod;
        x=x*x%mod;
        k>>=1;
    }
    return ans%mod;
}

il void Gauss_j(){
    for(re int i=1,r;i<=n;++i){
        r=i;
        for(re int j=i+1;j<=n;++j)
            if(a[j][i]>a[r][i]) r=j;
        if(r!=i) swap(a[i],a[r]);
        if(!a[i][i]){puts("No Solution");return;}

        int kk=qpow(a[i][i],mod-2); //求逆元
        for(re int k=1;k<=n;++k){
            if(k==i) continue;
            int p=a[k][i]*kk%mod;
            for(re int j=i;j<=(n<<1);++j)
                a[k][j]=((a[k][j]-p*a[i][j])%mod+mod)%mod;
        }

        for(re int j=1;j<=(n<<1);++j) a[i][j]=(a[i][j]*kk%mod);
        //更新当前行 如果放在最后要再求一次逆元,不如直接放在这里
    }

    for(re int i=1;i<=n;++i){
        for(re int j=n+1;j<(n<<1);++j) printf("%lld ",a[i][j]);
        printf("%lld\n",a[i][n<<1]);
    }
}
int main(){
    n=read();
    for(re int i=1;i<=n;++i)
        for(re int j=1;j<=n;++j)
            a[i][j]=read(),a[i][i+n]=1;

    Gauss_j();
    return 0;
}

原文地址:https://www.cnblogs.com/lfri/p/11618589.html

时间: 2024-10-11 05:31:44

求逆矩阵【模板】的相关文章

选主元的高斯-约旦(Gauss-Jordan)消元法解线性方程组/求逆矩阵

做数据结构课设时候查的资料,主要是看求逆矩阵方面的知识的. 选主元的高斯-约当(Gauss-Jordan)消元法在很多地方都会用到,例如求一个矩阵的逆矩阵.解线性方程组(插一句:LM算法求解的一个步骤),等等.它的速度不是最快的,但是它非常稳定(来自网上的定义:一个计算方法,如果在使用此方法的计算过程中,舍入误差得到控制,对计算结果影响较小,称此方法为数值稳定的),同时它的求解过程也比较清晰明了,因而人们使用较多.下面我就用一个例子来告诉你Gauss-Jordan法的求解过程吧.顺便再提及一些注

求最小正整数x,A^x=1(mod M)求阶模板

整数的阶:设a和n是互素的正整数,使得a^x=1(mod n)成立的最小的正整数x称为a模n的阶 //求阶模板:A^x=1(mod M),调用GetJie(A,M) //输入:10^10>A,M>1 //输出:无解返回-1,有解返回最小正整数x //复杂度:O(M^(0.5)) long long gcd(long long a,long long b) { if(b==0) return a; return gcd(b,a%b); } //欧拉函数:复杂度O(n^(0.5)),返回[1,n-

使用lapack库求逆矩阵

废话不多说,直接上代码: #include <string> #include "lapacke.h" #include "lapack_aux.h" int main(int argc,char** argv) { setlocale(LC_ALL,""); double a[] = { 3,-1,-1, 4,-2,-1, -3,2,1 }; int m = 3; int n = 3; int lda = 3; int ipiv[3

Poj 1144 Zoj 1311 求割点 模板

写这个就是为了手写一份好用的求割点模板: 吐槽下,题目中的 Each of the next at most N lines contains the number of a place followed by the numbers of some places to which there is a direct line from this place.  这个at most是不可信的,应该是用大于n行的测试数据,因为这个我WA了... #include <cstdio> #includ

字符串_KMP算法(求next[]模板 hdu 1711)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1711 问题描述:给两个序列a,b,长度分别为n,m(1<=n<=1000000,1<=m<=10000),问序列b是否为序列a的子序列,若是:返回a中最左边的与b相等的子序列的首元素下标:若不是,输出-1. 目的:方便以后查看KMP算法中next[]的模板 Number Sequence Time Limit: 10000/5000 MS (Java/Others)    Memory

(模板)求逆矩阵luoguP4783

题目链接: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

matlab中求逆矩阵的高斯消元法实现的代码

function qiuni =INV_GET(a)N=length(a);M=eye(N);%得到上三角矩?for i=1:N max=a(i,i); A=i; for j=i+1:N if(abs(a(j,i))>abs(max))%找最大值 max=a(j,i); A=j; end end for m=1:N temp1=a(i,m);%交换最大值值所在的行和当前行 a(i,m)=a(A,m); a(A,m)=temp1; temp2=M(i,m); M(i,m)=M(A,m); M(A,

exgcd求逆元模板

求x在模为mod时的逆元: exgcd(x,mod,x,y) 求出后,第三个参数就是逆元. mod可以不为质数 template <class T> T exgcd(T a, T b, T &x, T &y) { if (!b) { x = 1, y = 0; return a; } T t, ret; ret = exgcd(b, a%b, x, y); t = x, x = y, y = t - a / b*y; return ret; } 版权声明:本文为博主原创文章,未

二叉查找树的前序遍历,后序遍历和中序遍历互求算法模板

面试的痛 前几天去阿里面试,一时忘记了二叉树的前序遍历中序遍历和后序遍历的概念,已经想死了. 然后最近去腾讯面试,被问到怎么已知前序遍历/后序遍历 + 中序遍历,求后序遍历/前序遍历,看来这种问题很喜欢考. 其实这个问题想清楚了很简单,只要把这三个概念理解透彻就可以做出来了,比如前序遍历的第一个值一定是根节点,然后这个根节点对应到中序遍历里面,在中序遍历的这个值的两边的值,一定在以此节点为根节点的两个子树上,同理,后序遍历也一样. 已知前序遍历和后序遍历是不能求唯一的中序遍历树的. #inclu