double g[maxn][maxn]; voidGauss(){ bool F1 = 0, F2 = 0; for (int i = 1; i <= n; ++i) { int l = i; for (int j = i + 1; j <= n; ++j) if (fabs(g[j][i]) > fabs(g[l][i])) l = j; swap(g[l], g[i]); if (fabs(g[i][i]) < eps) { F1 = 1; continue; } for (int j = i + 1; j <= n + 1; ++j) g[i][j] /= g[i][i]; g[i][i] = 1; for (int j = 1; j <= n; ++j) { if (i == j) continue; for (int k = i + 1; k <= n + 1; ++k) g[j][k] -= g[j][i] * g[i][k]; g[j][i] = 0; } } for (int i = 1; i <= n; ++i) { double s = 0; for (int j = i; j <= n; ++j) s += g[i][j]; if (s < eps && g[i][n + 1] > eps) F2 = 1; } if (F2) cout << "No Solutions\n"; elseif (F1) cout << "Many Solutions\n"; elsefor (int i = 1; i <= n; ++i) cout << g[i][n + 1] << "\n"; }
矩阵求逆
然后这东西还能用来矩阵求逆
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
int g[maxn][2 * maxn]; voidGauss(){ for (int i = 1; i <= n; ++i) g[i][n + i] = 1; for (int i = 1; i <= n; ++i) { int pos = -1; for (int j = i; j <= n; ++j) if (g[j][i]) pos = j; if (pos == -1) returncout << "No Solution\n", void(); swap(g[pos], g[i]); ll inv = pow_mod(g[i][i], p - 2); for (int j = i; j <= 2 * n; ++j) g[i][j] = g[i][j] * inv % p; for (int j = 1; j <= n; ++j) { if (j == i) continue; for (int k = i + 1; k <= 2 * n; ++k) g[j][k] = (g[j][k] - (ll) g[j][i] * g[i][k]) % p; g[j][i] = 0; } } for (int i = 1; i <= n; ++i, cout << "\n") for (int j = n + 1; j <= 2 * n; ++j) cout << (g[i][j] + p) % p << " "; }
求解行列式
浮点数计算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
double g[maxn][maxn]; doubleGauss(int n){ double res = 1; for (int i = 1; i <= n; ++i) { int pos = -1; for (int j = i; j <= n; ++j) if (fabs(g[j][i]) > fabs(g[pos][i])) pos = j; if (pos == -1 || fabs(g[pos][i]) < eps) return0; swap(g[i], g[pos]); res *= pos == i ? 1 : -1; res *= g[i][i]; for (int j = i + 1; j <= n; ++j) for (int k = n; k >= i; --k) g[j][k] -= g[j][i] / g[i][i] * g[i][k]; } return res; }
模数不是质数,直接对两行做辗转相除,时间复杂度 $O(n^3)$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
int g[maxn][maxn]; intGauss(){ int res = 1; for (int i = 1; i <= n; ++i) { int pos = -1; for (int j = i; j <= n; ++j) if (g[j][i]) pos = j; if (pos == -1) return0; swap(g[i], g[pos]); res *= pos == i ? 1 : -1; for (int j = i + 1; j <= n; ++j) { if (g[j][i] < g[i][i]) swap(g[j], g[i]), res *= -1; while (g[i][i]) { int d = g[j][i] / g[i][i]; for (int k = i; k <= n; ++k) g[j][k] = (g[j][k] + 1ll * (p - d) * g[i][k]) % p; swap(g[i], g[j]), res *= -1; } swap(g[i], g[j]), res *= -1; } res = 1ll * res * g[i][i] % p; } return res; }
模数是质数
1 2 3 4 5 6 7 8 9 10 11 12 13
ll g[maxn][maxn]; intGauss(int n){ ll res = 1; for (int i = 1; i <= n; ++i) { int pos = -1; for (int j = i; j <= n; ++j) if (g[j][i]) pos = j; if (pos == -1) return0; swap(g[i], g[pos]); res *= pos == i ? 1 : -1; res = res * g[i][i] % p; ll inv = pow_mod(g[i][i], p - 2); for (int j = i + 1; j <= n; ++j) for (int k = n; k >= i; --k) g[j][k] = (g[j][k] - g[j][i] * inv % p * g[i][k]) % p; } return res; }
int g[maxn][maxn]; voidGauss(){ for (int i = 1; i <= n; ++i) { int p = -1; for (int j = i; j <= n; ++j) if (g[j][i]) p = j; if (p == -1) continue; swap(g[p], g[i]); for (int j = 1; j <= n; ++j) { if (i == j || !g[j][i]) continue; for (int k = i; k <= n + 1; ++k) g[j][k] ^= g[i][k]; } } for (int i = 1; i <= n; ++i) { int s = 0; for (int j = i; j <= n; ++j) s |= g[i][j]; if (!s && g[i][n + 1]) return (void) (cout << "No Solution\n"); } cout << "Y\n"; }
for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) { if (fabs(a[i][j]) < eps) continue; if (!p[j]) p[j] = i; double t = a[i][j] / a[p[j]][j]; for (int k = j; k <= m; ++k) a[i][k] -= t * a[p[j]][k]; }