矩阵及基本运算

矩阵表示

ICPC中的矩阵运算一般为方阵

struct Matrix{
    ll matrix[105][105];
};

int n;  //矩阵的阶数
矩阵初等变换
  1. 交换矩阵的两行或两列(对调 i , j i,j i,j,两行记为 r i ⟺ r j r_i \Longleftrightarrow r_j rirj
  2. 以一个非零数 k k k乘矩阵的某一行(列)所有元素(第 i i i行乘以 k k k记为 r i ∗ k r_i*k rik
  3. 把矩阵的某一行(列)所有元素乘以一个数 k k k后加到另一行(列)对应的元素(第 j j j行乘以 k k k加到第 i i i行记为 r i + k ∗ r j r_i+ k*r_j ri+krj
矩阵加法
Matrix add(Matrix a, Matrix b) {
    Matrix ans;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            ans.matrix[i][j] = (a.matrix[i][j] + b.matrix[i][j]) % Mod;
    return ans;
}
矩阵乘法

条件:仅考虑方阵相乘;口诀:前行乘后列

例如,对于 A × B = C , a i , j ∈ A , b i , j ∈ B , c i , j ∈ C A×B=C,a_{i,j}∈A,b_{i,j}∈B,c_{i,j}∈C A×B=C,ai,jA,bi,jB,ci,jC,则 c i , j = a i , 1 ∗ b 1 , j + a i , 2 ∗ b 2 , j + . . . + a i , n ∗ b n , j c_{i,j}=a_{i,1}*b_{1,j}+a_{i,2}*b_{2,j}+...+a_{i,n}*b_{n,j} ci,j=ai,1b1,j+ai,2b2,j+...+ai,nbn,j

Matrix mul(Matrix a, Matrix b) {
    Matrix ans;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++){
            ans.matrix[i][j]=0;
            for (int k = 1; k <= n; k++) {
                ans.matrix[i][j] += a.matrix[i][k] * b.matrix[k][j] % Mod;
                ans.matrix[i][j] %= Mod;
            }
        }
    return ans;
}

//矩阵快速幂
//如果求的是指数公差为1的连续矩阵,使用中间变量代替快速幂可以节省大量时间
Matrix qkp(Matrix mx, ll x) {
    Matrix ans;
    memset(ans.matrix, 0, sizeof ans.matrix);
    for (int i = 1; i <= n; i++) ans.matrix[i][i] = 1;
    while (x) {
        if (x & 1) ans = mul(ans, mx);
        mx = mul(mx, mx);
        x >>= 1;
    }
    return ans;
}
矩阵的逆

A A A可逆的充要条件为 ∣ A ∣ ≠ 0 |A|\neq0 A=0,其中 ∣ A ∣ |A| A称为矩阵的行列式

对于 n n n阶方阵 A A A ,若存在一个 n n n阶方阵 B B B ,使得 A B = B A = E AB=BA=E AB=BA=E ,其中 E E E为单位矩阵,则称 A A A为可逆阵且称 B B B A A A的逆矩阵,记作 A − 1 A^{-1} A1

二阶方阵

特殊的,对于二阶方阵 [ a b c d ] { \left[ \begin{array}{ccc} a & b \\ c & d \\ \end{array} \right ]} [acbd],其逆矩阵为 1 a d − b c [ d − b − c a ] \frac{1}{ad-bc}{ \left[ \begin{array}{ccc} d & -b \\ -c & a \\ \end{array} \right ]} adbc1[dcba]

高阶方阵

定义

A ∗ A^* A称为 A A A的伴随矩阵,其求法为 A i , j = ( − 1 ) i + j ∣ B ∣ A_{i,j}=(-1)^{i+j}|B| Ai,j=(1)i+jB,其中 B B B矩阵是除去第 i i i行第 j j j列剩下的数按照上下左右不变的关系凑成的 n − 1 n-1 n1阶矩阵。那么 A − 1 = 1 ∣ A ∣ A ∗ A^{-1}=\frac{1}{|A|}A^* A1=A1A

求解

  • A A A的同阶逆矩阵和 A A A放在一起形成 n ∗ 2 n n*2n n2n的新矩阵 B B B

  • B B B进行矩阵初等变换使 B B B的左半部分变为单位矩阵

  • 此时 B B B的右半部分即为逆矩阵 A − 1 A^{-1} A1

A − 1 ∗ ( A I ) = I A − 1 A^{-1}*(AI)=IA^{-1} A1(AI)=IA1

使用高斯-约旦消元即可解决,时间复杂度 O ( n 3 ) O(n^3) O(n3)

const int Mod = 1e9 + 7;

ll a[505][1005];

ll qkp(ll x, ll n, ll p) {
    ll ans = 1;
    x %= p;
    while (n) {
        if (n & 1) ans = ans * x % p;
        x = x * x % p;
        n >>= 1;
    }
    return ans;
}

void print(int n,int m){
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++) {
            printf("%lld%c", a[i][j], j == 2 * n ? '\n' : ' ');
        }
}

bool gauss_jordan(int n, int m) {
    int tmp;
    for (int i = 1; i <= n; i++) {
        tmp = i;
        while (!a[tmp][i] && tmp <= n) tmp++;
        if (tmp == n + 1) return false;
        for (int j = 1; j <= m; j++)
            swap(a[i][j], a[tmp][j]);
        ll p = a[i][i], inv = qkp(a[i][i], Mod - 2, Mod);
        for (int j = 1; j <= m; j++)
            a[i][j] = a[i][j] * inv % Mod;
        for (int j = 1; j <= n; j++) {
            if (i != j) {
                ll q = a[j][i];
                for (int k = 1; k <= m; k++)
                    a[j][k] = (a[j][k] - q * a[i][k] % Mod + Mod) % Mod;
            }
        }
        //print(n,m);
    }
    return true;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值