Martian148's blog Martian148's blog
首页
  • ICPC 算法笔记
  • ICPC 算法题解
  • 体系结构
  • 高等数学
  • 线性代数
  • 概率论与数理统计
  • 具体数学
  • Martian148的奇思妙想
  • 游记
  • 通识课笔记
关于
  • useful 网站
  • 友情链接
  • 分类
  • 归档

Martian148

一只热爱文科的理科生
首页
  • ICPC 算法笔记
  • ICPC 算法题解
  • 体系结构
  • 高等数学
  • 线性代数
  • 概率论与数理统计
  • 具体数学
  • Martian148的奇思妙想
  • 游记
  • 通识课笔记
关于
  • useful 网站
  • 友情链接
  • 分类
  • 归档
  • 线上赛板子(实时更新)
  • 数据结构

  • 数学

    • 数论
    • 多项式与生成函数
    • 线性代数
      • 矩阵乘法
      • 高斯消元
        • 高斯-约当消元法
      • 线性基的构造
      • 线性基的应用
    • 组合数学
    • 博弈论
  • 计算几何

  • 动态规划

  • 图论

  • 字符串

  • 杂项

  • 算法笔记
  • 数学
martian148
2024-08-31
目录

线性代数

# 线性代数

# 矩阵乘法

cij=∑k=1naikbkj c_{ij}=\sum_{k=1}^n a_{ik}b_{kj} cij​=k=1∑n​aik​bkj​

我们定义了乘法,那么我们就可以用使用快速幂来实现矩阵运算

常见的递推形式

  1. f(n)=a1f(n−1)+a2f(n−2)+⋯+akf(n−k)f(n)=a_1f(n-1)+a_2f(n-2)+\cdots+a_kf(n-k)f(n)=a1​f(n−1)+a2​f(n−2)+⋯+ak​f(n−k)
(f(n)f(n−1)f(n−2)⋮f(n−k+1))=(a1a2⋯ak10⋯001⋯0⋮⋱⋮0⋯10)(f(n−1)f(n−2)f(n−3)⋮f(n−k)) \begin{pmatrix} f(n) \\ f(n-1)\\ f(n-2)\\ \vdots\\f(n-k+1) \end{pmatrix} =\begin{pmatrix} a_1 &a_2 &\cdots &a_k \\ 1 & 0 & \cdots & 0\\ 0& 1& \cdots &0\\ \vdots& & \ddots &\vdots\\0 & \cdots & 1 & 0 \end{pmatrix} \begin{pmatrix} f(n-1) \\ f(n-2)\\ f(n-3)\\ \vdots\\f(n-k) \end{pmatrix} ⎝⎜⎜⎜⎜⎜⎜⎛​f(n)f(n−1)f(n−2)⋮f(n−k+1)​⎠⎟⎟⎟⎟⎟⎟⎞​=⎝⎜⎜⎜⎜⎜⎜⎛​a1​10⋮0​a2​01⋯​⋯⋯⋯⋱1​ak​00⋮0​⎠⎟⎟⎟⎟⎟⎟⎞​⎝⎜⎜⎜⎜⎜⎜⎛​f(n−1)f(n−2)f(n−3)⋮f(n−k)​⎠⎟⎟⎟⎟⎟⎟⎞​
  1. f(n)=a1f(n−1)+a2f(n−2)+Cf(n)=a_1f(n-1)+a_2f(n-2)+Cf(n)=a1​f(n−1)+a2​f(n−2)+C
(f(n)f(n−1)1)=(a1a2C100001)(f(n−1)f(n−2)1) \begin{pmatrix} f(n) \\ f(n-1)\\1 \end{pmatrix} =\begin{pmatrix} a_1 &a_2 &C \\ 1 & 0 & 0\\ 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} f(n-1) \\ f(n-2)\\1 \end{pmatrix} ⎝⎜⎛​f(n)f(n−1)1​⎠⎟⎞​=⎝⎜⎛​a1​10​a2​00​C01​⎠⎟⎞​⎝⎜⎛​f(n−1)f(n−2)1​⎠⎟⎞​

当然,这种形式很容易推到到有 kkk 项的形式

  1. f(n)=a1f(n−1)+a2f(n−2)+c2n2+c1n+c0f(n)=a_1f(n-1)+a_2f(n-2)+c_2n^2+c_1n+c_0f(n)=a1​f(n−1)+a2​f(n−2)+c2​n2+c1​n+c0​
(f(n)f(n−1)(n+1)2n+11)=(a1a2C2C1C010000001210001100001)(f(n−1)f(n−2)n2n1) \begin{pmatrix} f(n) \\ f(n-1)\\(n+1)^2\\n+1\\1 \end{pmatrix} =\begin{pmatrix} a_1 &a_2 &C_2&C_1&C_0 \\ 1&0&0&0&0\\ 0&0&1&2&1\\ 0&0&0&1&1\\ 0&0&0&0&1 \end{pmatrix} \begin{pmatrix} f(n-1) \\ f(n-2)\\n^2\\n\\1 \end{pmatrix} ⎝⎜⎜⎜⎜⎜⎛​f(n)f(n−1)(n+1)2n+11​⎠⎟⎟⎟⎟⎟⎞​=⎝⎜⎜⎜⎜⎜⎛​a1​1000​a2​0000​C2​0100​C1​0210​C0​0111​⎠⎟⎟⎟⎟⎟⎞​⎝⎜⎜⎜⎜⎜⎛​f(n−1)f(n−2)n2n1​⎠⎟⎟⎟⎟⎟⎞​
  1. f(n)=a11f(n−1)+a12,g(n)=a21f(n−1)+a22g(n−1)f(n)=a_{11}f(n-1)+a_{12},g(n)=a_{21}f(n-1)+a_{22}g(n-1)f(n)=a11​f(n−1)+a12​,g(n)=a21​f(n−1)+a22​g(n−1)
(f(n)g(n))=(a11a12a21a22)(f(n−1)g(n−1)) \begin{pmatrix} f(n) \\ g(n) \end{pmatrix} =\begin{pmatrix} a_{11}&a_{12}\\ a_{21}&a_{22} \end{pmatrix} \begin{pmatrix} f(n-1) \\ g(n-1) \end{pmatrix} (f(n)g(n)​)=(a11​a21​​a12​a22​​)(f(n−1)g(n−1)​)

这个是两个函数相互有关系,但这些关系都是线性的

  • 可以把矩阵运算看成和数值的运算类似,可以用线段树等数据结构维护

  • 动态DP

# 高斯消元

一个线性方程组有 mmm 个一次方程,nnn 个变量,把所有的系数写成一个 mmm 行 nnn 列的矩阵,把每个方程等号右侧的常

数放在最右列,得到一个 mmm 行 n+1n+1n+1 列的增广矩阵

高斯消元通过多次变换把方程组转化为多个一元一次方程

高斯消元具体步骤:

  • 枚举每一列,找到第一个

线性方程组的解有 333 种情况,有唯一解,有无穷多解,无解

# 高斯-约当消元法

高斯-约旦消元法的前提是 (假设有唯一解)

消元过程如下

  1. 从第 111 列开始,选择一个非 000 的系数(一般是最大值)所在的行,把这一行与第一行交换,此时 x1x_1x1​ 是主元
  2. 把 x1x_1x1​ 的系数转换成 1
  3. 利用主元 x1x_1x1​ 的系数,把其他行的这一列的主元消去
  4. 重复以上步数,直到把每行都变成只有对角线上存在主元,且系数都为 111,则答案就是最后一列的数字
image.png
std::string gauss(std::vector<std::vector<ld>> &a) { // 传入增广矩阵
    int n = a.size();
    int c = 0, r = 0;
    for (c = 0, r = 0, c < n; c ++) {
        int tmp = r;
        for (int i = r; i < n; i++)
            if (sgn(a[i][c]))
                tmp = i;
        if (sgn(a[tmp][c]) == 0)
            continue;

        std::swap(a[tmp], a[r]);

        for (int i = n; i >= c; i--)
            a[r][i] /= a[r][c];
        
        for (int i = r + 1; i < n; i++)
            if (sgn(a[i][c]))
                for (int j = n; j >= c; j--)
                    a[i][j] -= a[r][j] * a[i][c];
        r += 1;
    }
    if (r < n) {
        for (int i = r; i < n; i++)
            if (sgn(a[i][n]))
                return "NoSolution";
        return "InfSolution";
    }

    for (int i = n - 1; i >= 0; i--)
        for (int j = i + 1; j < n; j++)
            a[i][n] -= a[j][n] * a[i][j];
    
    return "OK";
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# 线性基

基是线性代数中的一个概念,一个向量空间可以由一组基线性组合而成

而线性基指的是模 222 域中的基

我们可以把这样一种线性的思想带到异或中去来组成线性基

线性基解决以下几类问题

从 nnn 个数中选出任意个数,使得异或和最大

一种朴素的思想是 2n2^n2n 次暴力枚举,但是由于每个数特别小,可能有多个组合能异或成为一个数,所以我们理论上来说答案只有 2m2^m2m 种,mmm 为最大的二进制位数

# 线性基的构造

  1. 非高斯消元构造

考虑到如果每个数的二进制位数都不同,那么这个集合 AAA 的线性基就是它本身

如果有两个数的二进制位数相同,那么通过 a1⊕a2a_1 \oplus a_2a1​⊕a2​ 可以把最高位去掉,所以我们枚举每个数去匹配位数,如果这一位有数了,那么就把当前枚举的这个数来异或上这个位的数,以此来消去枚举的这一个数的这一位上的一

  1. 高斯消元构造线性基

利用高斯消元来构造线性基会更加直观

把原数组构成的矩阵进行高斯消元,化成简化阶梯矩阵

如果后面有全 000 项,说明原来的集合 A{A}A 中存在一种方案使得异或和为 000

# 线性基的应用

最小异或和

只需要判断是否有 000 存在即可

最大异或和

若用基本方法求线性基,对于最后求出的基 PPP ,从大到小尝试异或每个元素,如果异或这个元素使得答案变大的话,那就异或它

如果用高斯消元的方法求线性基,由于只有对角线上存在 111 ,那么把 PPP 中所有数字异或起来就是答案

第 kkk 大/小异或和

高斯消元后,第 kkk 小异或和就是选上 kkk 二进制分解后为 111 的那些行

//带求第 k 大的板子
struct Linear_basis {
    i64 num[70]{}, zero = 0;
    const int B = 62;
    bool insert(i64 x) {
        for (int i = B; i >= 0; i --) if (x & (1ll << i)) {
            if (num[i]) x ^= num[i];
            else {
                num[i] = x;
                return true;
            }
        }
        zero ++;
        return false;
    }

    i64 query_min(i64 x) {
        for (int i = B; i >= 0; i --)
            x = std::min(x, x ^ num[i]);
        return x;
    }

    i64 query_max(i64 x) {
        for (int i = B; i >= 0; i --)
            x = std::max(x, x ^ num[i]);
        return x;
    }

    i64 query_kth(i64 k) {
        i64 x = 0;
        k >>= zero;
        std::vector<i64> p;
        for (int i = 0; i <= B; i ++) if (num[i]) p.emplace_back(num[i]);
        for (int i = (int)p.size() - 1; i >= 0; i --) {
            if (k & (1ll << i)) x = std::max(x, x ^ p[i]);
            else x = std::min(x, x ^ p[i]);
        }
        return x;
    }
} lb;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
上次更新: 2025/04/08, 18:03:31
多项式与生成函数
组合数学

← 多项式与生成函数 组合数学→

最近更新
01
Java基础语法
05-26
02
开发环境配置
05-26
03
pink 老师 JavaScript 学习笔记
05-26
更多文章>
Theme by Vdoing | Copyright © 2024-2025 Martian148 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式