矩阵的加减法和数乘为线性运算,均为逐个元素进行运算。
形式化地,即 A o p B = A i , j o p B i , j A\space op\space B=A_{i,j}\space op\space B_{i,j} A op B=Ai,j op Bi,j, o p op op 为 + / − +/- +/−。
矩阵乘法要求两个矩阵的行数和列数相等,设  
     
      
       
       
         A 
        
       
      
        A 
       
      
    A 为  
     
      
       
       
         P 
        
       
         × 
        
       
         M 
        
       
      
        P\times M 
       
      
    P×M 的矩阵, 
     
      
       
       
         B 
        
       
      
        B 
       
      
    B 为  
     
      
       
       
         M 
        
       
         × 
        
       
         Q 
        
       
      
        M\times Q 
       
      
    M×Q 的矩阵,则  
     
      
       
       
         C 
        
       
         = 
        
       
         A 
        
       
         × 
        
       
         B 
        
       
         , 
        
        
        
          C 
         
         
         
           i 
          
         
           , 
          
         
           j 
          
         
        
       
         = 
        
        
        
          ∑ 
         
         
         
           k 
          
         
           = 
          
         
           1 
          
         
        
          M 
         
        
        
        
          A 
         
         
         
           i 
          
         
           , 
          
         
           k 
          
         
        
       
         × 
        
        
        
          B 
         
         
         
           k 
          
         
           , 
          
         
           j 
          
         
        
       
      
        C=A\times B,C_{i,j}=\sum_{k=1}^{M}A_{i,k}\times B_{k,j} 
       
      
    C=A×B,Ci,j=∑k=1MAi,k×Bk,j。即矩阵  
     
      
       
       
         A 
        
       
      
        A 
       
      
    A 第  
     
      
       
       
         i 
        
       
      
        i 
       
      
    i 行  
     
      
       
       
         M 
        
       
      
        M 
       
      
    M 个数与矩阵  
     
      
       
       
         B 
        
       
      
        B 
       
      
    B 第  
     
      
       
       
         j 
        
       
      
        j 
       
      
    j 列  
     
      
       
       
         M 
        
       
      
        M 
       
      
    M 个数分别相乘再相加得到的,如下图。
 为了方便进行运算,我们会把矩阵设为二维数组,放在结构体里面,并重载运算符。
 这是我的矩阵加减乘法的模版。
struct matrix{
	int a[N][N];
	matrix(){memset(a,0,sizeof(a));}
	matrix operator +(const matrix& T) const{
		matrix res;
		for(int i=1;i<N;i++)
			for(int j=1;j<N;j++)
				res.a[i][j]=(a[i][j]+T.a[i][j])%mod;
		return res;
	}
	matrix operator -(const matrix& T) const{
		matrix res;
		for(int i=1;i<N;i++)
			for(int j=1;j<N;j++)
				res.a[i][j]=(a[i][j]-T.a[i][j])%mod;
		return res;
	}
	matrix operator *(const matrix& T) const{
		matrix res;//这个写法常数会小一些
		for(int i=1;i<N;i++){
			for(int k=1;k<N;k++){
				int r=a[i][k];
				for(int j=1;j<N;j++)
					res.a[i][j]=(res.a[i][j]+1ll*r*T.a[k][j])%mod;
			}
		}
		return res;
	}
};
由于矩阵也有乘法,那自然也有矩阵的快速幂,写法与普通快速幂同理。
 附洛谷矩阵快速幂模版代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define rd read()
const int N=110,mod=1e9+7;
int read(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
	while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
	return x*f;
}
int n,k;
struct matrix{
	int a[N][N];
	matrix(){memset(a,0,sizeof(a));}
	matrix operator +(const matrix& T) const{
		matrix res;
		for(int i=1;i<N;i++)
			for(int j=1;j<N;j++)
				res.a[i][j]=(a[i][j]+T.a[i][j])%mod;
		return res;
	}
	matrix operator -(const matrix& T) const{
		matrix res;
		for(int i=1;i<N;i++)
			for(int j=1;j<N;j++)
				res.a[i][j]=(a[i][j]-T.a[i][j])%mod;
		return res;
	}
	matrix operator *(const matrix& T) const{
		matrix res;
		for(int i=1;i<N;i++){
			for(int k=1;k<N;k++){
				int r=a[i][k];
				for(int j=1;j<N;j++)
					res.a[i][j]=(res.a[i][j]+1ll*r*T.a[k][j])%mod;
			}
		}
		return res;
	}
}M;
signed main(){
	n=rd,k=rd;
	for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) M.a[i][j]=rd;
	matrix res;
	for(int i=1;i<=n;i++) res.a[i][i]=1;//res要初始化为单位矩阵,即单位矩阵*M^K
	while(k){
		if(k&1) res=res*M;
		M=M*M,k>>=1;
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++) cout<<res.a[i][j]<<" ";
		cout<<"\n";
	}
	return 0;
}
而矩阵乘法的运用很多,最常用的便是加速递推,可以用其优化 dp(例如动态 dp)等等。最经典的便是斐波那契数列的应用,首先把原线性递推式转化为矩阵,然后用矩阵快速幂即可解决。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rd read()
ll read(){
	ll x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
	while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
	return x*f;
}
const int mod=1e9+7;ll n;
struct matrix{
	ll a[10][10];
	matrix(){memset(a,0,sizeof(a));}
	matrix operator *(const matrix& T)const{
		matrix res;
		for(int i=1;i<=2;i++){
			for(int k=1;k<=2;k++){
				ll r=a[i][k];
				for(int j=1;j<=2;j++)
					res.a[i][j]=(res.a[i][j]+1ll*r*T.a[k][j]%mod)%mod;
			}
		}
		return res;
	}
}bas,ans;
int main(){
	n=rd;ll x=n-2;
	if(n<=2){puts("1");return 0;}
	ans.a[1][1]=ans.a[1][2]=1;
	bas.a[1][1]=bas.a[1][2]=bas.a[2][1]=1;
	while(x){
		if(x&1) ans=ans*bas;
		bas=bas*bas,x>>=1;
	}
	printf("%lld\n",ans.a[1][1]%mod);
	return 0;
}
再来一道(P1939 矩阵加速(数列))
考虑 [ a i a i − 1 a i − 2 ] \begin{bmatrix} a_i& a_{i-1}&a_{i-2} \end{bmatrix} [aiai−1ai−2] 如何变为 [ a i + 1 a i a i − 1 ] \begin{bmatrix} a_{i+1}& a_{i}&a_{i-1} \end{bmatrix} [ai+1aiai−1],这道题非常显然。
[ a i + 1 a i a i − 1 ] × [ 1 1 0 0 0 1 1 0 0 ] \begin{bmatrix} a_{i+1}& a_{i}&a_{i-1} \end{bmatrix}\times \begin{bmatrix} 1 & 1 &0 \\ 0& 0& 1\\ 1& 0&0 \end{bmatrix} [ai+1aiai−1]× 101100010 。然后套个矩阵加速幂就可以了。










