window.cnblogsConfig = { homeTopImg: [ "https://cdn.luogu.com.cn/upload/image_hosting/clcd8ydf.png", "https://cdn.luogu.com.cn/upload/image_hosting/clcd8ydf.png" ], }

矩阵快速幂

推荐优秀讲解视频:https://www.bilibili.com/video/BV1fDA8z6Eo7/?spm_id_from=333.1387.favlist.content.click&vd_source=231102f0b172009ea518d223fb4ecb74

矩阵 \(A\)\(n\)\(m\) 列则为:

\[\begin{bmatrix}A_{1,1}&\cdots&A_{1,m}\\\vdots&\ddots&\vdots\\A_{n,1}&\cdots&A_{n,m}\end{bmatrix} \]

矩阵加法(减法)

则为两个行列长度相同的矩阵相加。即:

\[\begin{bmatrix}A_{1,1}&\cdots&A_{1,m}\\\vdots&\ddots&\vdots\\A_{n,1}&\cdots&A_{n,m}\end{bmatrix} + \begin{bmatrix}B_{1,1}&\cdots&B_{1,m}\\\vdots&\ddots&\vdots\\B_{n,1}&\cdots&B_{n,m}\end{bmatrix} = \begin{bmatrix}A_{1,1}+B_{1,1}&\cdots&A_{1,m}+B_{1,m}\\\vdots&\ddots&\vdots\\A_{n,1}+B_{n,1}&\cdots&A_{n,m}+B_{n,m}\end{bmatrix}\]

矩阵乘法

即一个 \(n \times u\) 的矩阵 \(A\) 与一个 \(n \times u\) 的矩阵 \(B\) 相乘然后得到一个 \(n \times m\) 的矩阵 \(C\)。图形化理解在:matrixmultiplication.xyz

具体地 \(A \times B = C,1\le i \le n,1\le j \le m\) 有:

\[C_{i,j} = \sum\limits_{ 1\le k \le u}A_{i,k} \times B_{k,j} \]

其实与 Floyd 十分相似。

矩阵性质

不满足 交换律,满足 结合律。

证明不满足交换律:

反证法,\(A(n,u) \times B(u,m) = C(n,m)\) 令其满足交换率,\(B(u,m) \times A(n,u) = C(u,u)\),若使得 \(C(u,u) = C(n,m)\) 当且仅当 \(u=n=m\) 下成立,证毕。

证明满足结合律:

\(A(n,u) \times B(u,v) \times C(v,m) = D(n,m)\),钦定 \(E = B \times C\),于是有 \(E(u,m)\),所以 \(A(n,u) \times B(u,v) \times C(v,m) = A(n,u) \times E(u,m) = D(n,m)\)\(A(n,u) \times B(u,v) \times C(v,m) =A(n,u) \times( B(u,v) \times C(v,m) )\)。证毕。

矩阵快速幂

由于矩阵乘法满足结合律,即快速幂本质。因此可以将快速幂应用到矩阵上。

具体地,时间复杂度为 \(O(n^3 \times \log x )\)

矩阵模板

struct mat{
	int a[N][N];
	mat(){mem(a,0);}
	void init(){
		For(i,1,n) a[i][i] = 1;
	}mat operator*(const mat& T) const{
		mat res;
		For(k,1,n) For(i,1,n) For(j,1,n) {
			(res.a[i][j] += (a[i][k] * T.a[k][j])) %= mod;
		}return res;
	}bool operator !=(const mat& T) const {
		For(i,1,n) For(j,1,n) if(a[i][j] != T.a[i][j]) return true;
		return false;
	}mat operator+(const mat& T) const{
		mat res;
		For(i,1,n) For(j,1,n) res.a[i][j] = (a[i][j] + T.a[i][j]) % mod;
		return res;
	}mat operator^(int x) const {
		mat res,bas; res.init();
		For(i,1,n) For(j,1,n) bas.a[i][j] = a[i][j];
		while(x){
			if(x & 1) {
				res = (res * bas);
			}bas = bas * bas;
			x >>= 1;
		}return res;		
	}
};

简单例题

P1962 斐波那契数列

考虑一个矩阵:

\(\begin{bmatrix}f_{n}\\f_{n-1}\end{bmatrix}\),如何从 \(\begin{bmatrix}f_{n-1}\\f_{n-2}\end{bmatrix}\) 转移来。也就是构造一个矩阵,乘上 \(\begin{bmatrix}f_{n-1}\\f_{n-2}\end{bmatrix}\) 得到 \(\begin{bmatrix}f_{n}\\f_{n-1}\end{bmatrix}\)。既然都是一个 $1\times 2 $ 的矩阵,那么肯定是一个 \(2\times 2\) 的矩阵作为中转。

那么考虑这么转移:

\(\begin{bmatrix}f_{n}\\f_{n-1}\end{bmatrix} = \begin{bmatrix}f_{n-1}\\f_{n-2}\end{bmatrix} \times \begin{bmatrix}{1}&{1}\\{1}&{0}\end{bmatrix}\)

那么实际意义呢?\(f_n\) 就是通过后面的 \(f_{n-1} + f_{n-2}\) 转过来的。然后 \(f_{n-1} = f_{n-1}\),满足了实际意义。于是我们发现对于每一个 \(3\le i \le n\),转移都是由这个矩阵 \(\begin{bmatrix}{1}&{1}\\{1}&{0}\end{bmatrix}\) 来的,所以那就是 \(\begin{vmatrix}{1}&{1}\\{1}&{0}\end{vmatrix}^{n-2}\)。然后初始状态就是 \(\begin{bmatrix}{1}\\{1}\end{bmatrix}\)

posted @ 2026-03-01 23:41  gsczl71  阅读(3)  评论(0)    收藏  举报