高斯消元
\(O(n^2m)\) 求解 \(n\) 元线性方程组 + 判断解的情况(可以是模意义下)
\(O(\frac{n^2m}{w})\) 求解 \(n\) 元异或方程组 + 判断解的情况
求解有唯一解的 \(n\) 元线性方程组
高斯消元基础
#1:高斯消元法
这里总结一下,对于一个有唯一解的增广矩阵,高斯消元分 5 步:
- 找主元
- 将当前行的方程主元系数化为一
- 将当前行以下的方程消去主元
- 如果还有别的主元,回到 1
- 对于消完的上三角矩阵一行行回带
版子:
inline void gauss()
{int i, j, k;double div;for (k = 1; k <= n; k ++){//1. 找主元int mi = k;for (i = k + 1; i <= n; i ++)if (fabs(g[i][k]) > fabs(g[mi][k]))mi = i;swap(g[mi], g[k]);//2. 将**当前行**的方程主元系数化为一div = g[k][k];for (j = k; j <= n + 1; j ++)g[k][j] /= div;//3. 将**当前行以下**的方程消去主元for (i = k + 1; i <= n; i ++){div = g[i][k];for (j = k; j <= n + 1; j ++)g[i][j] -= g[k][j] * div;}//4. 如果还有别的主元,回到 1}//5. 对于消完的上三角矩阵一行行回带for (k = n; k >= 1; k --){a[k] = g[k][n + 1];for (j = k + 1; j <= n; j ++)a[k] -= g[k][j] * a[j];}
}
#2:高斯-约旦消元法
注意到高斯消元法只将当前行以下的方程消去主元,这使得最后消完为一个上三角矩阵,导致还要一行行回带
如果这里我们直接将除了当前行以外的所有行都消去主元,最后的结果为一溜斜着的 1,可以省去回带
总结一下即分 4 步:
- 找主元
- 将当前行的方程主元系数化为一
- 将除当前行以外的方程消去主元
- 如果还有别的主元,回到 1
版子:
inline void gauss_jordan()
{int i, j, k;double div;for (k = 1; k <= n; k ++){//1. 找主元int mi = k;for (i = k + 1; i <= n; i ++)if (fabs(g[i][k]) > fabs(g[mi][k]))mi = i;swap(g[k], g[mi]);//2. 将**当前行**的方程主元系数化为一div = g[k][k];for (j = 1; j <= n + 1; j ++)g[k][j] /= div;//3. 将**除当前行以外**的方程消去主元for (i = 1; i <= n; i ++){if (i == k)continue;div = g[i][k];for (int j = 1; j <= n + 1; j ++)g[i][j] -= g[k][j] * div;}//4. 如果还有别的主元,回到 1}//无需回带for (i = 1; i <= n; i ++)a[i] = g[i][n + 1];
}
求解不保证有唯一解的 \(n\) 元线性方程组
这里探讨一下什么情况会出现无解和有无数解:
- 无解:解着解着发现形如 \(0=4\) 的神秘东西
- 无数解:方程给的太少或消成了 \(0=0\) 的东西
做法:
高斯消元法与高斯-约旦消元法是一样的
如果出现上述任意情况会在某一列找不到主元,就去下一列找。
同时维护一个变量 \(c\) 为待消去的主元编号,即整个过程进行完后 \(c\sim n\) 的方程未知数系数全为 0;
if (g[mi][k] == 0)continue;
swap(g[c], g[mi]);/*
和模版一样
*/c ++;
最后根据是 \(0=0\) 的情况还是 \(0=?\) 的情况判断有无解
if (c <= n)
{for (; c <= n; c ++)if (g[c][n + 1] != 0){printf("No Solution\n");exit(0);}printf("Infinity Solution\n");exit(0);
}
求解方程数量不保证等于未知数数量的 \(n\) 元线性方程组。
设方程数量为 \(m\),则无论是高斯消元法还是高斯-约旦消元法的做法都一样
记得改变一些枚举变量的上界,并在判断解的情况时注意分讨即可
if (c <= max(n, m))
{for (; c <= m; c ++)if (g[c][n + 1] != 0){printf("No Solution\n");exit(0);}if (c <= n){printf("Infinity Solution\n");exit(0);}
}
求解模 \(p\) 意义下的 \(n\) 元线性方程组
\(p\) 为质数
这种情况下可以直接除法改逆元,做就好了
\(p\) 为合数
做除法时暴力对被除数加 \(p\) 知道能整除为止,这个过程的复杂度没有保证,一般这种题出题人会有说明
例题:
P3389 【模板】高斯消元法
P2455 [SDOI2006] 线性方程组求解不保证有唯一解的 \(n\) 元线性方程组
UVA1564 Widget Factory
SP2883 WIDGET - Widget Factory求解模 \(p\) 意义下方程数量不保证等于未知数数量的 \(n\) 元线性方程组