「模板」高斯消元
构造上三角矩阵,对角线上的为该方程求解的未知数。
对于第 \(i\) 个方程,找到一个第 \(i\) 个未知数系数不为 \(0\) 的方程,交换两行。
将其他方程的第 \(i\) 个未知数系数都消为 \(0\)。
最后从下往上依次求解。
若第 \(n\) 个方程的第 \(n\) 个未知数系数为 \(0\),则方程组的解不唯一。
void gauss()
{
for(int i = 1; i <= n; i++)
{
for(int j = i + 1; j <= n && !a[i][i]; j++)
if(a[j][i]) swap(a[i], a[j])
for(int k = i + 1; k <= n; k++)
for(int j = n + 1; j >= i; j--)
a[k][j] -= a[k][i] / a[i][i] * a[i][j];
}
for(int i = n; i >= 1; i--)
{
for(int j = i + 1; j <= n; j++)
a[i][n + 1] -= a[i][j] * a[j][n + 1];
a[i][n + 1] /= a[i][i];
}
return;
}
void gauss()
{
for(int i = 1; i <= n; i++)
{
for(int j = i + 1; j <= n && !f[i][i]; j++)
if(f[j][i]) swap(f[i], f[j]);
int inv = qpow(f[i][i]);
for(int j = i + 1; j <= n; j++)
{
int tmp = 1ll * f[j][i] * inv % mod;
for(int k = i; k <= n + 1; k++)
f[j][k] = sub(f[j][k] - 1ll * f[i][k] * tmp % mod);
}
}
for(int i = n; i >= 1; i--)
{
for(int j = i + 1; j <= n; j++)
f[i][n + 1] = sub(f[i][n + 1] - 1ll * f[i][j] * f[j][n + 1] % mod);
f[i][n + 1] = 1ll * f[i][n + 1] * qpow(f[i][i]) % mod;
}
return;
}
$$A\ drop\ of\ tear\ blurs\ memories\ of\ the\ past.$$