博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
P4783 【模板】矩阵求逆
阅读量:6900 次
发布时间:2019-06-27

本文共 2609 字,大约阅读时间需要 8 分钟。

线性代数真的好珂怕……以下如果有漏洞欢迎指出

定义矩阵的三种初等行变换:

1.交换某两行

2.将某一行的所有元素乘上\(k\)(\(k\neq 0\))

3.将某一行的所有元素乘上\(k\)加到另一行去

每一个初等变换都对应一个初等矩阵,即矩阵\(A\)做某一线性变换等价于用一个对应的初等矩阵左乘\(A\)。若有一堆初等变换\(1,2,...l\),对应的初等矩阵分别为\(P_1,P_2,...,P_l\),那么经过这些线性变换后的矩阵即为\(P_l....P_2P_1A=PA\)\(P\)为之前那堆东西的乘积)

对于一个矩阵\(A\)\(A\)可逆的充分必要条件是\(A\)经过若干次初等行变换可以变成\(E\)\(E\)即单位矩阵),即存在一个矩阵\(P\)使得\(PA=E\),则\(P=A^{-1}\)

通过初等行变换使得\(A\)变为\(E\)并不困难,可以用高斯消元解决,先消成上三角矩阵,然后再消成对角矩阵

考虑怎么求出\(P\),因为有\(PA=E,PE=P\),如果我们同时维护两个矩阵\(A,B\),令\(B\)一开始时等于\(E\),在把\(A\)变为\(E\)的过程中对\(B\)也做相等的初等变换,那么当\(A\)变为\(E\)时,\(B\)也就变为了\(P\)(因为做初等行变换等价于被对应的初等矩阵左乘)

如果在高斯消元的过程中发现无法将\(A\)变为\(E\),输出无解即可

//minamoto#include
using namespace std;#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)char buf[1<<21],*p1=buf,*p2=buf;int read(){ int res,f=1;char ch; while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1); for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0'); return res*f;}char sr[1<<21],z[20];int C=-1,Z=0;inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}void write(int x){ if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x; while(z[++Z]=x%10+48,x/=10); while(sr[++C]=z[Z],--Z);sr[++C]=' ';}const int N=405,mod=1e9+7;int n;struct Matrix{ int a[N][N]; inline void clr(){memset(a,0,sizeof(a));} int* operator [](int x){return a[x];} void SWAP(int x,int y){for(int i=1;i<=n;++i)swap(a[x][i],a[y][i]);} //交换某两行 void MUL(int x,int k){for(int i=1;i<=n;++i)a[x][i]=(1ll*a[x][i]*k%mod+mod)%mod;} //将某一行的所有元素乘上k void MD(int x,int y,int k){for(int i=1;i<=n;++i)a[x][i]=((a[x][i]+(1ll*a[y][i]*k%mod))%mod+mod)%mod;} //将某一行的所有元素乘上k加到另一行去 void print(){ for(int i=1;i<=n;++i){ for(int j=1;j<=n;++j)write(a[i][j]); sr[++C]='\n'; } }}A,B;int ksm(int a,int b=(mod-2)){ int res=1; for(;b;b>>=1,a=1ll*a*a%mod)if(b&1)res=1ll*res*a%mod; return res;}int main(){// freopen("testdata.in","r",stdin); n=read(); for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)A[i][j]=read(); for(int i=1;i<=n;++i)B[i][i]=1; for(int i=1;i<=n;++i){ //消成上三角矩阵 if(!A[i][i]){ for(int j=i+1;j<=n;++j)if(A[j][i]){ A.SWAP(i,j),B.SWAP(i,j);break; } } if(!A[i][i])return puts("No Solution"),0; //如果消着消着某一列没有数了,说明无解 B.MUL(i,ksm(A[i][i])),A.MUL(i,ksm(A[i][i])); for(int j=i+1;j<=n;++j) B.MD(j,i,-A[j][i]),A.MD(j,i,-A[j][i]); } //消成对角矩阵 for(int i=n-1;i;--i)for(int j=i+1;j<=n;++j) B.MD(i,j,-A[i][j]),A.MD(i,j,-A[i][j]); B.print();return Ot(),0;}

转载于:https://www.cnblogs.com/bztMinamoto/p/9954406.html

你可能感兴趣的文章
离线快速部署Mirantis Openstack 9.0
查看>>
至少我还有腿
查看>>
怎样设计才能让文字排版更好看(三)
查看>>
【转】panabit+syslog打造中小型企业流量监控系统
查看>>
选高效服务器要精挑细选!擦亮双眼,拒绝杯具!
查看>>
Centos 7.1 RDO 安装 Liberty 问题及解决办法
查看>>
python制作的食物买卖存量计算程序
查看>>
yum命令——Linux下只下载不安装
查看>>
黑马程序员——集合篇
查看>>
memcached笔记
查看>>
CentOS yum安装Oracle10g
查看>>
MDT 2013 从入门到精通之SQL New MDT Database
查看>>
无线基础
查看>>
Percona Monitoring Plugins for Zabbix 报错一例
查看>>
SylixOS上EtherCAT实现
查看>>
CursorLoader用法
查看>>
区分不同手机平台客户端
查看>>
js阿拉伯数字转成汉字
查看>>
编码转化
查看>>
手写hashmap
查看>>