高斯消元 (浮点数运算)
inline void gauss(){
int i, j, k, l;
for(i = 1; i <= n; i++){
l = i;
for(j = i + 1; j <= n; j++)
if(fabs(matrix[j][i]) > fabs(matrix[l][i])) l = j;
if(l != i) for(j = i; j <= n + 1; j++)
swap(matrix[i][j], matrix[l][j]);
for(j = i + 1; j <= n; j++){
double tmp = matrix[j][i] / matrix[i][i];
for(k = i; k <= n + 1; k++)
matrix[j][k] -= matrix[i][k] * tmp;
}
}
for(i = n; i >= 1; i--){
double t = matrix[i][n + 1];
for(j = n; j > i; j--)
t -= ans[j] * matrix[i][j];
ans[i] = t / matrix[i][i];
}
}
行列式求值(取模运算)
int Gauss(int n){ //求解行列式的值
int ans = 1;
for(int i=2;i<=n;i++){
for(int k=i+1;k<=n;k++){
while(a[k][i]) {
int d = a[i][i] / a[k][i];
for(int j=i;j<=n;j++) a[i][j] = (a[i][j] - 1LL * d * a[k][j] % mod + mod) % mod;
swap(a[i],a[k]),ans = -ans; //必须交换,因为不是浮点数运算可能存在d = 0,导致a[k][i]一直不变
}
}
ans = 1LL * ans * a[i][i] % mod,ans = (ans + mod) % mod;
}
return ans;
}
逆矩阵
LL ext_gcd(LL a,LL b,LL &x,LL &y)
{
if(b==0)
{
x = 1, y = 0;
return a;
}
LL d = ext_gcd(b,a%b,y,x);
y -= a / b * x;
return d;
}
LL inverse(LL a)
{
LL x, y;
ext_gcd(a,mod,x,y);
return (x%mod+mod)%mod;
}
void add(LL &x ,LL y){
x += y;
if(x >= mod) x -= mod;
}
LL guass_inverse(){
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
C[i][j] = i == j?1:0;
for(int i = 0; i < n; i++){
int p = i;
for(int j = i; j < n; j++)
if(A[j][i] > A[p][i]) p = j;
swap(A[p],A[i]);
swap(C[p],C[i]);
if(A[i][i] == 0) return -1;
LL inva = inverse(A[i][i]);
for(int j = 0; j < n; j++){
C[i][j] = C[i][j] * inva % mod;
A[i][j] = A[i][j] * inva % mod;
}
for(int j = 0; j < n; j++)
if(j != i){
LL z = A[j][i];
for(int k = 0; k < n; k++){
add(C[j][k],mod - C[i][k]*z%mod);
add(A[j][k],mod - A[i][k]*z%mod);
}
}
}
return 1;
}