(模板)求逆矩阵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 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;
}

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

时间: 2024-11-02 15:37:08

(模板)求逆矩阵luoguP4783的相关文章

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

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

第十六周oj刷题——Problem K: 填空题:类模板---求数组的最大值

Description 类模板---求数组的最大值 找出一个数组中的元素的最大值,数组大小为10.(用类模板来实现) 数组元素类型作为类模板的参数. Input 10个int型数据 10个double型数据 10个char型数据 10gestring型数据 Output 10个int型数据的最大值 10个double型数据的最大值 10个char型数据的最大值 10个string型数据的最大值 Sample Input 1 3 5 7 9 8 6 4 2 0 1.2 3.4 5.66 7.8 9

OJ刷题之《函数模板--求n个数之和》

题目描述 利用函数模板求4个数的和. 部分代码已给定如下,只需要提交缺失的代码. #include <iostream> using namespace std; /* 补充缺少代码 */ int main() { double result; unsigned char c1,c2,c3,c4; cin>>c1>>c2>>c3>>c4; result = sum<unsigned char>(c1,c2,c3,c4); cout&l

使用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

求逆矩阵【模板】

题目 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&

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,

AtCoder Beginner Contest 142【D题】【判断素数的模板+求一个数的因子的模板】

D - Disjoint Set of Common Divisors Problem Statement Given are positive integers AA and BB. Let us choose some number of positive common divisors of AA and BB. Here, any two of the chosen divisors must be coprime. At most, how many divisors can we c

模板 求GCD&amp;LCM

求最大公倍数 1 int GCD(int a,int b) 2 { 3 if(a % b == 0) return b; 4 else 5 return GCD(b,a%b); 6 } 求最小公倍数 1 int LCM(int a,int b) 2 { 3 return a*a/GCD(a,b); //最小公倍数等于两数乘积除以最大公约数 4 }

C++模板求n!与1+2+...n

//求n!与1+2+...n #include <iostream> using namespace std; template<int _N=0> class A { public: //static int const result = 3*A<_N-1>::result; enum{result=_N*A<_N-1>::result};//求n! //enum{result=_N+A<_N-1>::result};//求1+...n. };