矩阵乘法是个很高端的东西。
注意事项: 以下的讲述下标都从0开始
矩阵是什么?
不解释
矩阵加减法?
矩阵加矩阵,就将对应的加上。
矩阵加常数,就将每一个元素都加上这个常数。
减法同理。
矩阵乘法
一张好图,在这里发现的,方便理解矩阵乘法。
一个 m∗n 的的A矩阵,和一个 n∗p 的B矩阵相乘,将得到一个 m∗p 的矩阵C
C(i,j)=∑k=1nA(i,k)∗B(k,j)
可以简单地理解为,A中i行的元素,与B中j列的元素,对应相乘得到的和。
矩阵乘法的运算定律
(1) 不满足交换律
(2) 满足结合律:(AB)C=A(BC)
(3) 满足分配律:(A+B)C=AC+BC A(B+C)=AB+AC
模板
template <typename T,int M,int N>
struct Matrix
{
T mat[M][N];
inline Matrix(){
memset(mat,0,sizeof mat);}
inline T* operator[](int i){
return mat[i];}
};
template <typename T,int M,int N,int P>
inline Matrix<T,M,P> operator*(const Matrix<T,M,N>& x,const Matrix<T,N,P>& y)
{
Matrix<T,M,P> ret;
int i,j,k;
for (i=0;i<M;++i)
for (j=0;j<P;++j)
for (k=0;k<N;++k)
ret.mat[i][j]+=x.mat[i][k]*y.mat[k][j];
return ret;
}
template <typename T,typename T_>
inline T pow(T x,T_ y)
{
T ret=x;
--y;//这两句话可以忽略初值问题,但y<=0时就悲剧了
while (y)
{
if (y&1)
ret=ret*x;
y>>=1;
x=x*x;
}
return ret;
}
矩阵乘法的应用
矩阵乘法可以优化时间。
将某些操作转化为矩阵乘法的形式,就可以用快速幂减少时间。因为矩阵乘法满足结合律。
例题一 斐波那契数列
描述
题目背景
大家都知道,斐波那契数列是满足如下性质的一个数列:
• f(1) = 1
• f(2) = 1
• f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 为整数)题目描述
请你求出 f(n) mod 1000000007 的值。
输入格式:
·第 1 行:一个整数 n
输出格式:
第 1 行: f(n) mod 1000000007 的值
输入样例#1:
5
输出样例#1:
5
输入样例#2:
10
输出样例#2:
55
说明
对于 60% 的数据: n ≤ 92
对于 100% 的数据: n在long long(INT64)范围内。
解法
这是一道裸斐波拉契数列。传统递推是O(N)的,显然会炸。
斐波拉契数列有个通项,但我们在这里用矩阵乘法解决。
我们知道f(n)是由f(n-1)和f(n-2)推过来的,不妨设一个1*2的矩阵
A=[f(n−2)f(n−1)]
现在我们要通过A推出B
B=[f(n−1)f(n)]=[f(n−1)f(n−2)+f(n−1)]
我们要求出一个2*2的 转移矩阵 T,满足
A∗T=B
即
[f(n−2)f(n−1)]∗T=[