矩阵是种神奇的东西啊~~
简单讲讲矩阵的运算法则
+
+
加法,两个行数和列数分别相同的矩阵可以进行加法运算,Ans矩阵每个位置上的数为两个矩阵相应位置上的数的和
−
−
减法,与加法类似两个行数和列数分别相同的矩阵可以进行减法运算,Ans矩阵每个位置上的数为两个矩阵相应位置上的数的差
∗
∗
数乘,表现为一个数乘一个矩阵,具体效果就是矩阵的每个位置上的数都乘上需要数乘的数。
以上三种运算都比较简单,直接可以理解。接下来讲一个复杂的东西。
×
×
叉乘,一个矩阵乘上另一个矩阵,只有在前面的矩阵的行数等于第二个矩阵的列数时可以进行运算(可以看出来,矩阵的叉乘不满足交换律),先写一下矩阵叉乘的定义:
假设
A×B=C,A,B,C
A
×
B
=
C
,
A
,
B
,
C
均为矩阵。
Ci,j=∑lenk=1Ai,k∗Bk,j
C
i
,
j
=
∑
k
=
1
l
e
n
A
i
,
k
∗
B
k
,
j
len
l
e
n
是A的行数或B的列数。
上面的这个图中的
C
C
矩阵是3*3的,图中只画出了一个。
,这下应该解释清楚了。
因为矩阵乘法满足交换律,所以对矩阵乘方可以用快速幂加速,我的快速幂板子请戳这
typedef long long ll;
struct Matrix {
int row, col, limit;
std::vector< std::vector< ll > > num;
Matrix() {
row = col = 0;
limit = 0x3f3f3f3f;
num.clear();
}
Matrix(int _row, int _col, int _limit) {
this->row = _row;
this->col = _col;
this->limit = _limit;
num.clear();
num.resize(row + 1);
for (int i = 1; i <= row; i++)
num[i].resize(col + 1);
}
Matrix(int _row, int _col, int _limit, long long *list) {
this->row = _row;
this->col = _col;
this->limit = _limit;
num.clear();
num.resize(row + 1);
for (int i = 1; i <= _row; i++) {
num[i].resize(col + 1);
for (int j = 1; j <= _col; j++)
num[i][j] = list[(i - 1) * _row + j];
}
}
Matrix operator + (const Matrix& rhs) {
assert(this->row == rhs.row && this->col == rhs.col);
for (int i = 1; i <= row; i++)
for (int j = 1; j <= col; j++)
this->num[i][j] += rhs.num[i][j],
this->num[i][j] %= limit;
return *this;
}
Matrix operator - (const Matrix& rhs) {
assert(this->row == rhs.row && this->col == rhs.col);
for (int i = 1; i <= row; i++)
for (int j = 1; j <= col; j++)
this->num[i][j] -= rhs.num[i][j],
this->num[i][j] %= limit;
return *this;
}
Matrix operator * (const long long& rhs) {
for (int i = 1; i <= this->row; i++)
for (int j = 1; j <= this->col; j++)
this->num[i][j] *= rhs,
this->num[i][j] %= this->limit;
}
Matrix operator * (const Matrix& rhs) {
assert(this->col == rhs.row);
Matrix ans = Matrix(this->row, col, this->limit);
for (int i = 1; i <= this->row; i++)
for (int j = 1; j <= rhs.col; j++)
for (int k = 1; k <= this->col; k++)
ans.num[i][j] += this->num[i][k] * rhs.num[k][j],
ans.num[i][j] %= this->limit;
return ans;
}
Matrix operator ^ (ll p) {
assert(this->row == this->col);
Matrix ans = Matrix(this->row, this->col, this->limit);
for (int i = 1; i <= this->row; i++)
ans.num[i][i] = 1;
while (p) {
if (p & 1) ans = ans * *this;
*this = *this * *this;
p >>= 1;
}
return ans;
}
};
写了若干个构造函数,含义应该也很明显了,
矩阵快速幂嘛,,,整数快速幂里面拿过来的啦~~~,修改一下就OK了。
虽说重载^纯属个人喜好。。。