原题链接 https://www.luogu.org/problemnew/show/P4783

一道模板题,更重要的省选难度.....

题目要求的是一个n*n的逆矩阵,还要对大数取膜。

普通高中生:这…………

来一步一步分析:

(1)怎么求逆矩阵?

首先,我们要开一个二维数组,范围是a[401][801];

why?这就和求逆矩阵有关啦。

先输入n*n的矩阵,紧接着在右边罗一个n*n的单位矩阵

然后我们对左半边的矩阵进行高斯消元消成了单位矩阵,则此时右半边的单位矩阵就被消成了左半边原矩阵的逆矩阵

    scanf("%lld",&n);
for(int i=;i<=n;i++)
{
for(int j=;j<=n;j++)
scanf("%lld",&a[i][j]);
a[i][i+n]=; //在输入矩阵的同时在右边罗列一个n*n的单位矩阵
}

接着就要对左半边的矩阵进行高斯消元,怎么高斯消元呢?其实就是把高斯消元的板子套上去啊。P3389

这是模板高斯消元的代码:

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int n,pl;
double a[][];
int main()
{
cin>>n;
for(int i=;i<=n;i++)
for(int j=;j<=n+;j++)
cin>>a[i][j];
for(int i=;i<=n;i++)
{
pl=i;
while(a[pl][i]==&&pl<=n)
{pl++;} // 判断第i列首元素非0的最上行,因为第i行第i列元素不能为0
if(pl==n+) {cout<<"No Solution";return ;} //一直判到了n+1行,可是一共才只有n行,说明有一列全为0,无解
for(int j=;j<=n+;j++) //将第i行第i列元素不为0的那一行与当前行交换
swap(a[i][j],a[pl][j]);
double k=a[i][i]; //让第i行每个元素都除以a[i][i]使得a[i][i]为1
for(int j=;j<=n+;j++)
a[i][j]=a[i][j]/k; //将第i行第i列的元素消成1,注意同行进行同样的操作
for(int j=;j<=n;j++)
{
if(i!=j) //将第i列除了第i行的元素全消成0
{ //方法是第j行每个元素a[j][m]都减去a[j][1]*a[i][m]
double ki=a[j][i];
for(int m=;m<=n+;m++)
a[j][m]=a[j][m]-ki*a[i][m];
}
}
}
for(int i=;i<=n;i++)
printf("%.2lf\n",a[i][n+]);
return ;
}

(2)怎么对有理数取膜?

这也是道模板题…………P2613

#include<iostream>
#include<cstdio>
using namespace std;
const long long mod=;
inline long long read()
{
long long t=;
char ch=getchar();
while(ch<''||ch>'') ch=getchar();
while(ch>=''&&ch<='')
{
t=(t*+(ch-''))%mod;
ch=getchar();
}
return t;
}
int exgcd(long long a,long long b,long long &x,long long &y)
{
if(b==)
{
x=;y=;
return a;
}
long long r=exgcd(b,a%b,x,y);
long long q=x;
x=y;
y=q-a/b*y;
return r;
}
int main()
{
long long a,b,x,y;
a=read();
b=read();
if(b==)
{
cout<<"Angry!";
return ;
}
exgcd(b,mod,x,y);
x=(x%mod+mod)%mod;
printf("%lld",(a%mod*x%mod)%mod);
return ;
}

证明过程:

1.费马小定理

如果p是一个质数,而整数a不是p的倍数,则有a^(p-1)≡1(mod p)。

此题已经明确给出mod数19260817,显然它是一个质数,那么我们就可以用费马小定理转化一下,如下:

因为a^(p-1)≡1(mod p)

所以a^(p-2)≡a^(-1) (mod p)    (A)

所以c=a/b=a*b^(-1)≡a*b^(p-2) (mod p)

证毕!

所以我们就可以将在膜p意义下的a/b转化成a*b^(p-2)的形式,所以我们只要求出b^(p-2)就大功告成啦,具体做法用快速幂。

2.扩展欧几里德

上面已经证过求在膜p意义下的a/b就是求a*b^(-1),b^(-1)就是b的逆元

下面给出求b的逆元的一种方法:

若存在一个数x,满足bx≡1 (mod p),那么x就是b的逆元

可将bx≡1 (mod p)进一步转化:

bx-1≡0 (mod p)

bx-1=-yp    (注:这里说一下为什么是-y,其实这里是不是正负无所谓,写成负的更便于理解)

bx+py=1

二者一结合,就是此题的代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<math.h>
using namespace std;
const int mod=;
long long n,a[][];
long long x,y;
inline int read()
{
int t=;
char ch=getchar();
while(ch<''||ch>'') ch=getchar();
while(ch>=''||ch<='')
{
t=t*+(ch-'');
ch=getchar();
}
}
int inv(long long a,long long b)
{
long long ans=;
while(b)
{
if(b&) ans=ans*a%mod;
a=a*a%mod;
b>>=;
}
return ans%mod;
}
int main()
{
scanf("%lld",&n);
for(int i=;i<=n;i++)
{
for(int j=;j<=n;j++)
scanf("%lld",&a[i][j]);
a[i][i+n]=; //在输入矩阵的同时在右边罗列一个n*n的单位矩阵
}
for(int i=;i<=n;i++) //进行高斯消元
{
for(int j=i;j<=n;j++)
{
if(a[j][i])
{
for(int q=;q<=*n;q++)
swap(a[j][q],a[i][q]);
break;
}
}
if(!a[i][i]) //判无解
{
cout<<"No Solution";return ;
}
long long k=inv(a[i][i],mod-)%mod; //利用费马小定理来求逆元
for(int j=;j<=*n;j++) a[i][j]=a[i][j]*k%mod; //利用矩阵性质将a[i][i]消成1,注意同样对右半边的单位矩阵操作
for(int j=;j<=n;j++) //将第i列的其他行消成0
{
if(j!=i)
{
long long k=a[j][i];
for(int m=i;m<=*n;m++) //注意同时对右半边的单位矩阵进行操作
{
a[j][m]=a[j][m]-k*a[i][m];
a[j][m]=(a[j][m]%mod+mod)%mod;
}
}
}
}
for(int i=;i<=n;i++)
{
for(int j=+n;j<=*n;j++) //输出右半边的矩阵就是逆矩阵啦
cout<<a[i][j]<<" ";
cout<<endl;
}
return ; //完结撒花
}

话说真的这道题就是两个模板题的结合qwq~

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

  1. luoguP4783 [模板]矩阵求逆 线性代数

    求\(n^2\)的矩阵的逆 翻了翻题解,看到了初等矩阵这个东西,突然想起来在看线代的时候看到过.... 然后又温习了一遍线性代数的知识 不妨设\(PA = E\),其中\(P\)是一堆初等矩阵的积(必 ...

  2. 洛谷 P4783 【模板】矩阵求逆

    题目分析 模板题. #include <bits/stdc++.h> using namespace std; typedef long long ll; const int mod=1e ...

  3. LUOGU P4783 【模板】矩阵求逆(高斯消元)

    传送门 解题思路 用高斯消元对矩阵求逆,设\(A*B=C\),\(C\)为单位矩阵,则\(B\)为\(A\)的逆矩阵.做法是把\(B\)先设成单位矩阵,然后对\(A\)做高斯消元的过程,对\(B\)进 ...

  4. 题解 P4783 【【模板】矩阵求逆】

    题目大意 求一个N×N的矩阵的逆矩阵.答案对10^9+7取模.N<=400 前置知识 矩阵的初等变换 矩阵的逆定义为 A*B=E(E为单位矩阵)此时B为A的逆 思路 如果矩阵有逆 那么这个矩阵经 ...

  5. 洛谷P4783 【模板】矩阵求逆(高斯消元)

    题意 题目链接 Sol 首先在原矩阵的右侧放一个单位矩阵 对左侧的矩阵高斯消元 右侧的矩阵即为逆矩阵 // luogu-judger-enable-o2 #include<bits/stdc++ ...

  6. LG4783 【模板】矩阵求逆

    P4783 [模板]矩阵求逆 题目描述 求一个$N\times N$的矩阵的逆矩阵.答案对$10^9+7$取模. 输入输出格式 输入格式: 第一行有一个整数$N$,代表矩阵的大小: 从第$2$行到第$ ...

  7. matrix矩阵求逆 与解方程模板 留做备用 (有bug,待补充)

    // // main.cpp // 矩阵求逆 // // Created by 唐 锐 on 13-6-20. // Copyright (c) 2013年 唐 锐. All rights reser ...

  8. Luogu4783 【模板】矩阵求逆(高斯消元)

    对矩阵进行高斯消元直至消为单位矩阵,并在另一个单位矩阵上对其做同样的操作即可. 模意义下的高斯消元可以直接计算系数来避免整行的辗转相除. 还不知道有什么用. #include<iostream& ...

  9. OpenCV2邻域和模板操作

    在图像处理中,通过当前位置的邻域像素计算新的像素值是很常见的操作.当邻域包含图像的上几行和下几行时,就需要同时扫描图像的若干行,这就是图像的邻域操作了.至于模板操作是实现空间滤波的基础,通常是使用一个 ...

随机推荐

  1. RMQ求LCA

    题目链接 rmq求LCA,interesting. 一直没有学这玩意儿是因为CTSC的Day1T2,当时我打的树剖LCA 65分,gxb打的rmq LCA 45分... 不过rmq理论复杂度还是小一点 ...

  2. loj#2531. 「CQOI2018」破解 D-H 协议(BSGS)

    题意 题目链接 Sol 搞个BSGS板子出题人也是很棒棒哦 #include<bits/stdc++.h> #define Pair pair<int, int> #defin ...

  3. 参观微软Serbia开发中心和Office365 2019-01-31活动感悟

    这是<国外线下技术俱乐部建设>系列文章之一.   该活动网址是:https://www.meetup.com/ITPro-Serbia/events/258352104/ 活动内容是讲Of ...

  4. 红米Note 5A完美卡刷开发版获得ROOT超级权限的方法

    小米的手机不同手机型号一般情况官方论坛都提供两个不同的系统,大概可分为稳定版和开发版,稳定版没有提供root权限管理,开发版中就支持了root权限,在很多工作的时候我们需要使用的一些功能强大的APP, ...

  5. 微信小程序(六) 文章详情静态页面detail

    文章详情静态页面detail:

  6. centos7网络配置方法

    方法一:nmtui    这个是字符界面的图形化网络配置工具 方法二:nmcli 命令行配置 方法三:直接vim /etc/sysconfig/network-scripts/ens----  编辑 ...

  7. 面向对象_new,__eq__,__hash__

    老师博客:http://www.cnblogs.com/Eva-J/articles/7351812.html __new__ __init__是一种初始化的方法 __new__是构建方法,创建一个对 ...

  8. Nginx解读内置非默认模块 ngx_http_stub_status_module

    1 Background http://nginx.org/en/docs/http/ngx_http_stub_status_module.html ngx_http_stub_status_mod ...

  9. particles.js在vue上的运用

    转:https://www.jianshu.com/p/c52b3e91c94f 知乎的首页后面的粒子动效总觉得很炫酷,搜了一下,发现是用particles.js编写的.刚好目前的项目是利用vue框架 ...

  10. 用CMD打开chrome并导航到百度(golang)

    首选在cmd中输入(注意:根据你的电脑路径修改,可能是Progra~1): C:\Progra~\Google\Chrome\Application\chrome.exe www.baidu.com ...