线性代数基础 Linear Algebra Basics

线性代数基础 \(Linear Algebra Basics\)

向量

向量定义

一个 \(n\) 维向量 \(V\) 可以表示为:

\V = (v_1, v_2, \\dots, v_n) \\

点积运算

两个 \(n\) 维向量 \(p\) 和 \(q\) 的点积:

\p \\cdot q = \\sum_{i=1}\^n p_i q_i \\

示例

\\\begin{aligned} p \&= (1, 2, 3) \\\\ q \&= (4, 5, 6) \\\\ p \\cdot q \&= 1 \\times 4 + 2 \\times 5 + 3 \\times 6 = 32 \\end{aligned} \\

矩阵

矩阵定义

一个 \(m \times n\) 的矩阵 \(A\):

\A = \\begin{pmatrix} a_{11} \& a_{12} \& \\cdots \& a_{1n} \\\\ a_{21} \& a_{22} \& \\cdots \& a_{2n} \\\\ \\vdots \& \\vdots \& \\ddots \& \\vdots \\\\ a_{m1} \& a_{m2} \& \\cdots \& a_{mn} \\end{pmatrix} \\

特殊矩阵

单位矩阵 \(I_n\):

\I_n = \\begin{pmatrix} 1 \& 0 \& \\cdots \& 0 \\\\ 0 \& 1 \& \\cdots \& 0 \\\\ \\vdots \& \\vdots \& \\ddots \& \\vdots \\\\ 0 \& 0 \& \\cdots \& 1 \\end{pmatrix} \\

矩阵运算

矩阵加法

\(A + B)_{ij} = A_{ij} + B_{ij} \\

矩阵数乘

\(kA)_{ij} = k \\cdot A_{ij} \\

矩阵乘法

对于 \(A_{m \times n}\) 和 \(B_{n \times p}\):

\(AB)_{ij} = \\sum_{k=1}\^n A_{ik} B_{kj} \\

注意 : 矩阵乘法不满足交换律 !!!

再说一遍 :矩阵乘法不满足交换律 !!!

最后一遍 :矩阵乘法不满足交换律 !!!

示例

\\\begin{pmatrix} 1 \& 2 \\\\ 3 \& 4 \\end{pmatrix} \\begin{pmatrix} 5 \& 6 \\\\ 7 \& 8 \\end{pmatrix} = \\begin{pmatrix} 1 \\times 5 + 2 \\times 7 \& 1 \\times 6 + 2 \\times 8 \\\\ 3 \\times 5 + 4 \\times 7 \& 3 \\times 6 + 4 \\times 8 \\end{pmatrix} = \\begin{pmatrix} 19 \& 22 \\\\ 43 \& 50 \\end{pmatrix} \\


代码模板

c++ 复制代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

const int N = 500 + 5;
const int MOD = 1e9 + 7;

int n, p, m;
int A[N][N], B[N][N], C[N][N];

void read() {
	cin >> n >> p >> m;

	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= p; j++) {
			cin >> A[i][j];
			A[i][j] = (A[i][j] % MOD + MOD) % MOD;
		}
	}

	for (int i = 1; i <= p; i++) {
		for (int j = 1; j <= m; j++) {
			cin >> B[i][j];
			B[i][j] = (B[i][j] % MOD + MOD) % MOD;
		}
	}
}

void mul() {
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			ll sum = 0;
			for (int k = 1; k <= p; k++) {
				sum += (1ll * A[i][k] * B[k][j]) % MOD;
				sum %= MOD;
			}
			
			C[i][j] = sum;
		}
	}
}

void print() {
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cout << C[i][j] << " ";
		}
		
		cout << "\n";
	}
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	read();
	
	mul();
	
	print();

	return 0;
}

矩阵转置

\(A\^T)_{ij} = A_{ji} \\

矩阵快速幂

定义

对于方阵 \(A\):

\A\^k = \\underbrace{A \\times A \\times \\cdots \\times A}_{k \\text{次}} \\

快速算法

利用二进制分解:

\A\^k = \\prod_{i=0}\^{\\lfloor \\log_2 k \\rfloor} A\^{2\^i} \\


代码模板

c++ 复制代码
#include <bits/stdc++.h>
using namespace std;

const int N = 1e2 + 3;
const int MOD = 1e9 + 7;

struct Matrix {
	int n;
	int mat[N][N];
	
	Matrix(int _n = 0) : n(_n) { memset(mat, 0, sizeof(mat)); }

	void E() { for (int i = 1; i <= n; i ++) mat[i][i] = 1; }
};

Matrix mul(Matrix a, Matrix b) {
	int n = a.n;
	Matrix ret(n);
	
	for (int i = 1; i <= n; i ++) {
		for (int j = 1; j <= n; j ++) {
			for (int k = 1; k <= n; k ++) {
				ret.mat[i][j] = (ret.mat[i][j] + 1ll * a.mat[i][k] * b.mat[k][j]) % MOD;
			}
		}
	}
	
	return ret;
}

Matrix quick_pow(Matrix x, long long p) {
	int n = x.n;
	Matrix ret(n);
	ret.E();
	
	while (p) {
		if (p & 1) ret = mul(ret, x);
		x = mul(x, x);
		p >>= 1;
	}
	
	return ret;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	int n;
	long long k;
	cin >> n >> k;
	Matrix a(n);

	for (int i = 1; i <= n; i ++) {
		for (int j = 1; j <= n; j ++) {
			cin >> a.mat[i][j];
			a.mat[i][j] = (a.mat[i][j] % MOD + MOD) % MOD;
		}
	}

	Matrix res = quick_pow(a, k);

	for (int i = 1; i <= n; i ++) {
		for (int j = 1; j <= n; j ++) {
			cout << res.mat[i][j] << ' ';
		}
		cout << '\n';
	}

	return 0;
}

常系数齐次线性递推与矩阵加速 !!!

一、线性递推的数学本质

1. 递推关系的矩阵表示

对于k阶线性递推关系:

\f_n = \\sum_{i=1}\^k c_i f_{n-i} \\quad (n \> k) \\

存在转移矩阵 \(A\) 满足:

\\\underbrace{ \\begin{bmatrix} f_n \\\\ f_{n-1} \\\\ \\vdots \\\\ f_{n-k+1} \\end{bmatrix} }_{V_n} = A \\times \\underbrace{ \\begin{bmatrix} f_{n-1} \\\\ f_{n-2} \\\\ \\vdots \\\\ f_{n-k} \\end{bmatrix} }_{V_{n-1}} \\

2. 转移矩阵的结构特性

矩阵 \(A\) 具有如下标准形式:! ! !

\A = \\begin{bmatrix} c_1 \& c_2 \& \\cdots \& c_{k-1} \& c_k \\\\ 1 \& 0 \& \\cdots \& 0 \& 0 \\\\ 0 \& 1 \& \\cdots \& 0 \& 0 \\\\ \\vdots \& \\vdots \& \\ddots \& \\vdots \& \\vdots \\\\ 0 \& 0 \& \\cdots \& 1 \& 0 \\end{bmatrix}_{k \\times k} \\

构造原理

- 第一行:直接对应递推系数

- 次对角线:全1元素用于"移位"记录历史状态


二、矩阵加速的严格推导

1. 递推展开过程

通过递归展开可得:

\V_n = A \\times V_{n-1} = A\^2 \\times V_{n-2} = \\cdots = A\^{n-k} \\times V_k \\

其中初始向量:

\V_k = \\begin{bmatrix} f_k \\\\ f_{k-1} \\\\ \\vdots \\\\ f_1 \\end{bmatrix} \\

2. 时间复杂度分析

计算过程分为两步:

  1. 计算矩阵幂 \(A^{n-k}\)
    • 使用快速幂算法
    • 每次矩阵乘法 \(O(k^3)\) 时间
    • 总时间 \(O(k^3 \log n)\)
  2. 矩阵-向量乘法
    • \(O(k^2)\) 时间

三、推广到非齐次情况

1. 含常数项的递推

对于递推式:

\f_n = \\sum_{i=1}\^k c_i f_{n-i} + d \\

构造技巧

  • 升维处理:

    \\\widetilde{V}_n = \\begin{bmatrix} V_n \\\\ 1 \\end{bmatrix} = \\begin{bmatrix} f_n \\\\ \\vdots \\\\ f_{n-k+1} \\\\ 1 \\end{bmatrix} \\

  • 扩展转移矩阵:

    \\\widetilde{A} = \\begin{bmatrix} A \& \\begin{matrix} d \\\\ 0 \\\\ \\vdots \\\\ 0 \\end{matrix} \\\\ 0 \\cdots 0 \& 1 \\end{bmatrix} \\

2. 含多项式项的递推

对于递推式:

\f_n = \\sum_{i=1}\^k c_i f_{n-i} + P(m) \\

其中 \(P(m)\) 是 \(m\) 次多项式

构造方法

  • 需要跟踪的变量:
    • \(f_n\) 及其历史项
    • \(m^j \ (j=0,1,...,m)\)
  • 转移矩阵维度:
    • 总维度 \(= k + (m + 1)\)

四、典型例题的解析理论

例题1:三阶递推问题

给定:

\f_n = f_{n-1} + f_{n-3} \\quad (n \\geq 4) \\

初始条件:\(f_1=f_2=f_3=1\)

矩阵构造过程

确定状态向量:

\V_n = \\begin{bmatrix} f_n \\\\ f_{n-1} \\\\ f_{n-2} \\end{bmatrix} \\

建立方程关系:

\\\begin{cases} f_n = 1·f_{n-1} + 0·f_{n-2} + 1·f_{n-3} \\\\ f_{n-1} = 1·f_{n-1} + 0·f_{n-2} + 0·f_{n-3} \\\\ f_{n-2} = 0·f_{n-1} + 1·f_{n-2} + 0·f_{n-3} \\end{cases} \\

得到转移矩阵:

\A = \\begin{bmatrix} 1 \& 0 \& 1 \\\\ 1 \& 0 \& 0 \\\\ 0 \& 1 \& 0 \\end{bmatrix} \\

求解步骤

计算幂次:

\power = n - 3 \\

最终表达式:

\\\begin{bmatrix} f_n \\\\ f_{n-1} \\\\ f_{n-2} \\end{bmatrix} = A\^{n-3} \\times \\begin{bmatrix} f_3 \\\\ f_2 \\\\ f_1 \\end{bmatrix} \\


五、理论边界与限制

1. 适用条件

  • 必须严格满足线性关系
  • 系数必须为常数(不能是 \(n\) 的函数)

2. 不适用情况

  • 非线性递推:

    \f_n = f_{n-1} \\times f_{n-2} \\

  • 变系数递推:

    \f_n = n \\cdot f_{n-1} \\

3. 维度爆炸问题

当递推式中包含:

  • 多个多项式项
  • 高次多项式时

会导致转移矩阵维度急剧增加,实际应用中需权衡:

\\\text{矩阵维度} = k + \\sum_{i=1}\^m (\\deg(P_i) + 1) \\


六、理论延伸

1. 与特征根法的联系

矩阵特征多项式:

\\\det(\\lambda I - A) = 0 \\

正是递推关系的特征方程,二者通解形式一致。

2. 广义矩阵加速

对于分块矩阵情形,可处理:

  • 多个相互关联的递推式
  • 二维递推问题
  • 带有模运算的特殊递推

代码模板

c++ 复制代码
#include <bits/stdc++.h>
using namespace std;

using ll = long long;

const int MOD = 1e9 + 7;
const int N = 5;

struct Matrix {
	int n;
	int mat[N][N];

	Matrix(int _n = 0) : n(_n) { memset(mat, 0, sizeof(mat)); }

	void E() { for (int i = 1; i <= n; i++) mat[i][i] = 1; }
};

Matrix A(3), init(3);

void pre() {
	A.mat[1][1] = 1;
	A.mat[1][3] = 1;
	A.mat[2][1] = 1;
	A.mat[3][2] = 1;

	init.mat[1][1] = 1;
	init.mat[2][1] = 1;
	init.mat[3][1] = 1;
}

Matrix mul(Matrix a, Matrix b) {
	int n = a.n;
	Matrix ret(n);

	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			for (int k = 1; k <= n; k++) {
				ret.mat[i][j] = (ret.mat[i][j] + 1ll * a.mat[i][k] * b.mat[k][j]) % MOD;
			}
		}
	}

	return ret;
}

Matrix quick_pow(Matrix x, ll p) {
	int n = x.n;
	Matrix ret(n);
	ret.E();

	while (p) {
		if (p & 1) ret = mul(ret, x);
		x = mul(x, x);
		p >>= 1;
	}

	return ret;
}

void solve(int n) {
	if (n <= 3) {
		cout << "1\n";
		return;
	}

	Matrix ret = quick_pow(A, n - 3);
	Matrix ans = mul(ret, init);

	cout << ans.mat[1][1] << '\n';
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	int T; cin >> T;
	
	pre();
	
	while (T--) {
		int n; cin >> n;
		
		solve(n);
	}

	return 0;
}

线性方程组

增广矩阵表示

方程组:

\\\begin{cases} a_{11}x_1 + a_{12}x_2 + \\cdots + a_{1n}x_n = b_1 \\\\ a_{21}x_1 + a_{22}x_2 + \\cdots + a_{2n}x_n = b_2 \\\\ \\vdots \\\\ a_{m1}x_1 + a_{m2}x_2 + \\cdots + a_{mn}x_n = b_m \\end{cases} \\

增广矩阵:

\\\left( \\begin{array}{cccc\|c} a_{11} \& a_{12} \& \\cdots \& a_{1n} \& b_1 \\\\ a_{21} \& a_{22} \& \\cdots \& a_{2n} \& b_2 \\\\ \\vdots \& \\vdots \& \\ddots \& \\vdots \& \\vdots \\\\ a_{m1} \& a_{m2} \& \\cdots \& a_{mn} \& b_m \\end{array} \\right) \\

高斯消元法

基本操作

  1. 交换两行
  2. 某行乘以非零常数
  3. 将某行的倍数加到另一行

消元步骤

  1. 化为上三角矩阵
  2. 回代求解

示例

\\\begin{aligned} \&\\left( \\begin{array}{ccc\|c} 1 \& 1 \& 1 \& 6 \\\\ 2 \& 1 \& 1 \& 10 \\\\ 1 \& 2 \& 1 \& 10 \\end{array} \\right) \\\\ \\rightarrow \&\\left( \\begin{array}{ccc\|c} 1 \& 1 \& 1 \& 6 \\\\ 0 \& -1 \& -1 \& -2 \\\\ 0 \& 1 \& 0 \& 4 \\end{array} \\right) \\\\ \\rightarrow \&\\left( \\begin{array}{ccc\|c} 1 \& 0 \& 0 \& 1 \\\\ 0 \& 1 \& 0 \& 4 \\\\ 0 \& 0 \& 1 \& -2 \\end{array} \\right) \\end{aligned} \\

解得:

\x = 1, \\quad y = 4, \\quad z = -2 \\


代码模板

c++ 复制代码
#include <bits/stdc++.h>
using namespace std;

const int N = 1e2 + 10;

int n;

double a[N][N];

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin >> n;
	for (int i = 1; i <= n; i ++) {
		for (int j = 1; j <= n + 1; j ++) {
			cin >> a[i][j];
		}
	}
	
	for (int i = 1; i <= n; i ++) {
		int p = i;
		
		while (p <= n && a[p][i] == 0) p ++;
		if (p == n + 1) {
			cout << "No Solution" << '\n';
			return 0;
		}
		
		for (int j = 1; j <= n + 1; j ++)
			swap(a[i][j], a[p][j]);

		double tmp = a[i][i];
		for (int j = 1; j <= n + 1; j ++)
			a[i][j] /= tmp;

		for (int j = 1; j <= n; j ++) {
			if (i == j) continue;
			
			tmp = a[j][i];
			
			for (int k = 1; k <= n + 1; k ++) {
				a[j][k] -= a[i][k] * tmp;
			}
		}
	}
	
	cout << fixed << setprecision(2);
	for (int i = 1; i <= n; i ++)
		cout << a[i][n + 1] << '\n';

	return 0;
}

部分由 AI 润色

相关推荐
ZhouDevin37 分钟前
算法论文/数据集5——AlignPrune(CVPR2026)基于样本损失时间序列精确识别噪声样本
算法
十铭忘1 小时前
HMM(隐马尔可夫模型)的理解7——Baum–Welch 算法
人工智能·算法
明月_清风2 小时前
十大经典排序算法 Go 实现全解:从入门到面试通关
后端·算法·排序算法
liliangcsdn2 小时前
如何对IC时间序列进行汇总统计分析示例
人工智能·算法·机器学习
土司大王2 小时前
LeetCode hot100——缺失的第一个正数
数据结构·算法·leetcode
Cccp.1232 小时前
【leetcode】(二)认识O(NlogN)的排序
算法·leetcode
明月_清风3 小时前
算法时间复杂度:给小白的一堂"算快慢"课
后端·算法
vivo互联网技术3 小时前
TinySR:面向真实世界图像超分辨率的轻量级扩散模型
人工智能·算法
不会就选b3 小时前
数据结构之栈的算法题(OJ)
linux·数据结构·算法