矩阵
矩阵的定义:
矩阵(matrix)其实就是一个二维数组,第 \(i\) 行 \(j\) 列的元素即为 \(a_{i,j}\)
矩阵的运算:
加减:
它们均为逐个元素进行。只有同型矩阵之间可以对应相加减。
转置:
矩阵的转置,就是在矩阵的右上角写上转置「T」记号,表示将矩阵的行与列互换。
对称矩阵转置前后保持不变。
乘法:
矩阵的乘法是向量内积的推广。
矩阵相乘只有在第一个矩阵的列数和第二个矩阵的行数相同时才有意义。
设 \(A\) 为 \(P \times M\) 的矩阵,\(B\) 为 \(M \times Q\) 的矩阵,设矩阵 \(C\) 为矩阵 \(A\) 与 \(B\) 的乘积,
其中矩阵 \(C\) 中的第 \(i\) 行第 \(j\) 列元素可以表示为:
\(C_{i,j}= \sum^{M}_{k=1}A_{i,k}*B_{k,j}\)
其实就相当于一个线性方程组。
注意:矩阵乘法满足结合律,但不满足交换率
幂:
矩阵的幂 \(A^k\) 即为 \(k\) 个 \(A\) 相乘。
因为矩阵乘法满足结合律所以我们可以使用快速幂来优化。
时间复杂度:\(O(n^3 \log k)\)
代码:
struct matrix{
int t[N][N], row, col;
matrix(int _r, int _c, bool I){
row = _r, col = _c;
memset(t, 0, sizeof t);
if(I) for(int i = 0; i < row; i++) t[i][i] = 1;
}
};
matrix operator * (matrix a, matrix b){
matrix c(a.row, b.col, 0);
for(int i = 0; i < a.row; i++){
for(int j = 0; j < b.col; j++){
for(int k = 0; k < a.col; k++){
c.t[i][j] = (c.t[i][j] + a.t[i][k] * b.t[k][j] % mod) % mod;
}
}
}
return c;
}
matrix qpow(matrix x, int y){
matrix ret(x.row, x.col, 1);
for(; y; y >>= 1, x = x * x) if(y & 1) ret = ret * x;
return ret;
}