当前位置: 首页 > news >正文

洛谷 P4783 【模板】矩阵求逆 题解

洛谷 P4783 【模板】矩阵求逆 题解

算法模板 | 线性代数 | 高斯约旦消元

题目信息
  • 题目链接:https://www.luogu.com.cn/problem/P4783
  • 难度:提高+/省选- 困难
  • 知识点:矩阵求逆、高斯-约旦消元、模运算

一、题目简述

给定一个 (n) 阶矩阵 (A),求它的逆矩阵 (A^{-1}),满足 (A \times A^{-1} = E)((E) 为单位矩阵)。
若矩阵不可逆,输出 No Solution
所有运算在模 (10^9+7) 意义下进行,输出逆矩阵的每个元素。

数据范围

  • (1 \le n \le 400)
  • (0 \le A_{ij} < 10^9+7)
  • 模数 (MOD = 10^9+7)(质数)

二、题目分析

核心思路

矩阵求逆的经典方法是高斯-约旦消元法(我们线性代数学过的增广矩阵与初等行变换):

  1. 构造增广矩阵 ([A | E]),其中 (E) 是 (n) 阶单位矩阵
  2. 对增广矩阵做初等行变换,将左半部分 (A) 化为单位矩阵 (E)
  3. 此时右半部分即为 (A) 的逆矩阵 (A^{-1})
  4. 若消元过程中某列主元为0,说明矩阵不可逆

关键细节

  • 模 (10^9+7) 下的除法等价于乘以乘法逆元(费马小定理求逆)
  • 高斯-约旦消元无需回代,直接将主元化为1,其他列化为0,代码更简洁
  • 时间复杂度 (O(n^3)),(n=400) 时可通过

三、代码实现

#include <stdio.h>#define MOD 1000000007LLlong long matrix[405][805];
int n;// 快速幂求逆元
long long power(long long a, long long b) {long long res = 1;a %= MOD;while (b) {if (b & 1) res = (res * a) % MOD;a = (a * a) % MOD;b >>= 1;}return res;
}long long get_inv(long long n) {return power(n, MOD - 2);
}int main() {if (scanf("%d", &n) != 1) return 0;// 1. 构造增广矩阵 [A | I]for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {scanf("%lld", &matrix[i][j]);}matrix[i][i + n] = 1; // 右侧补单位阵}// 2. 高斯-约旦消元for (int i = 0; i < n; i++) {// 寻找主元,如果 matrix[i][i] 为 0,则与下方交换int pivot = i;while (pivot < n && matrix[pivot][i] == 0) pivot++;if (pivot == n) {printf("No Solution\n");return 0;}// 交换行if (pivot != i) {for (int j = 0; j < 2 * n; j++) {long long temp = matrix[i][j];matrix[i][j] = matrix[pivot][j];matrix[pivot][j] = temp;}}// 将当前行主元化为 1long long inv = get_inv(matrix[i][i]);for (int j = i; j < 2 * n; j++) {matrix[i][j] = (matrix[i][j] * inv) % MOD;}// 消除其他行的第 i 列for (int k = 0; k < n; k++) {if (k != i) {long long factor = matrix[k][i];for (int j = i; j < 2 * n; j++) {matrix[k][j] = (matrix[k][j] - factor * matrix[i][j] % MOD + MOD) % MOD;}}}}// 3. 输出右半部分 [I | A^-1]for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {printf("%lld%c", matrix[i][j + n], j == n - 1 ? '\n' : ' ');}}return 0;
}

四、复杂度分析

  • 时间复杂度:(O(n^3))
    高斯-约旦消元的三重循环,(n=400) 时总运算量约 (6.4 \times 10^7),可在时间限制内通过。
  • 空间复杂度:(O(n^2))
    存储 (n \times 2n) 的增广矩阵,(n=400) 时占用空间约 (1.28 \times 10^6),完全满足内存限制。

五、常见问题与避坑

  1. 模运算负数处理:减法后需 + MOD % MOD,避免出现负数
  2. 主元选择:必须从第 (i) 行开始找,不能从第1行开始
  3. 逆元计算:模数 (10^9+7) 是质数,用费马小定理 (a^{MOD-2}) 求逆
  4. 数组大小:增广矩阵需开 (n \times 2n),避免越界

六、总结

矩阵求逆是线性代数的核心算法,高斯-约旦消元是最常用的实现方式:

  • 核心步骤:构造增广矩阵 → 主元归一 → 初等行变化消元

七、学习提高

  • 本人做这一部分的时候线性代数还没学到这一部分,如同样想了解的可以观看宋浩老师的课程【初等行变换法求逆矩阵】
    https://www.bilibili.com/video/BV1h7pteyEww?spm_id_from=333.788.videopod.episodes&vd_source=c435966a6ee44f8c5dd8206fec75523a&p=23
  • 若想进一步学习如何用编程From Scratch的解决线性代数问题,可以去了解Data Science from Scratch(Joel Grus),这本书语言是python。代码:
    https://github.com/joelgrus/data-science-from-scratch
http://www.jsqmd.com/news/557242/

相关文章:

  • 单细胞RNA测序中AUCell与AddModuleScore的基因集活性评分实战指南
  • 2026年3月电力电缆生产厂家推荐,中低压、低压、中压、变频等全品类覆盖 - 品牌2026
  • 从“注意力”到“多头”:用图书馆找书的例子,彻底搞懂Transformer的自注意力机制
  • SDMatte在UI设计协作中应用:Figma插件对接+透明PNG自动同步
  • GemPy:地质建模范式的革命性转变与三维地质结构自动重建
  • K8s CronJob配置避坑指南:从并发策略到历史记录,这些细节你注意了吗?
  • 论文降AI率全流程教程:检测→分析→降AI→复查四步走完全指南 - 我要发一区
  • 别再复制Word公式了!用TexStudio写LaTeX论文,这几个高效技巧帮你省下半天时间
  • ChatGPT突然变‘笨’了?别慌,手把手教你用F12开发者工具快速恢复(附降智自检清单)
  • AM2315温湿度传感器I²C驱动与多平台移植指南
  • 为什么要配置环境变量?
  • ChatGPT/DeepSeek写的论文降AI率教程:分步骤解决高AI率问题 - 我要发一区
  • 锂电池测试实验:从基础到实战的全面解析
  • 如何用MAT修复老照片?3个实用技巧让破损图像重获新生
  • 从等高线到坡度分析:QGIS中DEM创建与地形分析全流程实战
  • GHelper:华硕笔记本轻量级性能控制工具技术指南
  • C#项目里OpenCVSharp报System.Memory版本冲突?手把手教你精准降级到4.0.1.2
  • 如何免费体验原神抽卡:最真实的祈愿模拟器完整指南
  • 避坑指南:当你的Caffeine本地缓存和Redis数据打架时该怎么办?(附完整代码示例)
  • SQL Server 2022最新版实战:从安装配置到基础查询全流程指南
  • CentOS 7 上跑不动 Chrome?3 种低风险方案解决 glibc 版本冲突
  • AI写作大师Qwen3-4B真实体验:CPU环境下的智能写作效果实测
  • 群决策环境下危险品运输风险评价方法附Matlab代码
  • 手把手教你给普冉PY32F071(Cortex-M0)移植FreeRTOS,从工程搭建到点灯测试
  • PlatformIO-lwIP:FreeRTOS与libopencm3嵌入式TCP/IP集成方案
  • 解决openssl动态库链接错误:EVP_mdc2符号未定义问题
  • MOOTDX:为什么这个Python通达信数据接口是量化投资的终极解决方案?
  • 告别手动收集!用OWASP Amass自动化你的子域名侦察(附Kali/Windows/Mac安装配置)
  • RP2040W异步TCP库:基于事件驱动的嵌入式网络通信
  • LFM2.5-1.2B-Thinking真实体验:AMD CPU上239 tok/s,移动端也能跑