Template -「矩阵 - 行列式」

#include <cstdio>

int Abs(int x) { return x < 0 ? -x : x; }
int Max(int x, int y) { return x > y ? x : y; }
int Min(int x, int y) { return x < y ? x : y; }

int read() {
    int x = 0, k = 1;
    char s = getchar();
    while (s < '0' || s > '9') {
        if (s == '-')
            k = -1;
        s = getchar();
    }
    while ('0' <= s && s <= '9') {
        x = (x << 3) + (x << 1) + (s ^ 48);
        s = getchar();
    }
    return x * k;
}

void write(int x) {
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    if (x > 9)
        write(x / 10);
    putchar(x % 10 + '0');
}

void print(int x, char c) {
    write(x);
    putchar(c);
}

const int MAXN = 2e2 + 5;

struct Matrix {
    typedef long long LL;

    int n, m, mod;
    LL w[MAXN][MAXN];

    void clear() {
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++) w[i][j] = 0;
    }

    void init() {
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++)
                if (i == j)
                    w[i][j] = 1;
                else
                    w[i][j] = 0;
    }

    const Matrix operator*(const Matrix &x) const {
        Matrix ans;
        ans.n = n;
        ans.m = x.m;
        for (int i = 1; i <= ans.n; i++)
            for (int j = 1; j <= ans.m; j++)
                for (int k = 1; k <= m; k++) ans.w[i][j] = (ans.w[i][j] + (w[i][k] * x.w[k][j]) % mod) % mod;
        return ans;
    }

    LL Det() { \\ 这里是 mod 不为质数的行列式求法,若为质数可直接高斯消元。
        LL ans = 1;
        bool flag;
        for (int i = 1; i <= n; i++) {
            if (!w[i][i]) {
                flag = false;
                for (int j = i + 1; j <= n; j++)
                    if (w[j][i]) {
                        flag = true;
                        for (int k = i; k <= m; k++) w[i][k] ^= w[j][k] ^= w[i][k] ^= w[j][k];
                        ans = -ans;
                        break;
                    }
                if (!flag)
                    return 0;
            }
            for (int j = i + 1; j <= n; j++)
                while (w[j][i]) {
                    LL t = w[i][i] / w[j][i];
                    for (int k = i; k <= m; k++) {
                        w[i][k] = (w[i][k] - t * w[j][k]) % mod;
                        w[i][k] ^= w[j][k] ^= w[i][k] ^= w[j][k];
                    }
                    ans = -ans;
                }
            ans = ans * w[i][i] % mod;
        }
        return (ans + mod) % mod;
    }
}
posted @ 2021-10-18 15:58  STrAduts  阅读(39)  评论(0编辑  收藏  举报