矩阵,主要用于递推/(dp)优化,以及特别的题目。
运算:
注意,矩阵有(+,-,*,pow)以及矩阵的逆等运算。本文讨论入门的(+,-,*,pow).
对于加法:
[left[
egin{matrix}
1&3&5\
2&4&7\
end{matrix}
ight]+
left[
egin{matrix}
2&9&7\
12&9&3\
end{matrix}
ight]
]
即为:
[left[
egin{matrix}
3&12&12\
14&13&10\
end{matrix}
ight]
]
就是遵循按位相加的原则,减法同理。
注意矩阵的加减法必须是同行数同列数的矩阵。
对于乘法:
定义(C_{i,j})是(A,B)两个矩阵乘完之后的矩阵对应的第(i)行第(j)列的元素。
规定(A)为(P*M)的矩阵,(B)为(M*Q)的矩阵。
则有:
[C_{i,j}=sum_{k=1}^{M}{A_{i,k}*B_{k,j}}
]
也可以简单理解为,对应行乘以对应列。
矩阵快速幂#
就是一个矩阵的乘方。
注意,只有方阵才有乘方,即列数等于行数((n*n))
同样地,若求一个矩阵的(k)次方,可以和二进制快速幂一样,重载乘法即可。
注意提到一个概念:矩阵中,和(1)一样的存在是谁呢?我们称之为 $单位矩阵 ,就是对角线上都是(1),其它位置都是(0)的矩阵。
通过矩阵乘法定义会发现,一个矩阵乘以单位矩阵(称之为(I))等于它本身。
一个简单的单位矩阵:
[left[
egin{matrix}
1&0&0\
0&1&0\
0&0&1\
end{matrix}
ight]
]
代码实现:
struct matrix{
ll a[4][4];
matrix(){memset(a,0,sizeof(a));}
matrix operator*(const matrix&b)const{
matrix res;
for(int i=1;i<=2;++i)
for(int j=1;j<=2;++j)
for(int k=1;k<=2;++k)
res.a[i][j]=(res.a[i][j]+a[i][k]*b.a[k][j])%mod;
return res;
}
}base,ans;
void qpow(int b){
while(b){
if(b&1)ans=ans*base;
base=base*base;b>>=1;
}
}
待补(QwQ)