矩阵模板

高斯消元 (浮点数运算)

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;
}

 

posted @ 2019-10-10 20:29  月光下の魔术师  阅读(10)  评论(0)    收藏  举报