[笔记]线性基

线性基的定义:若干 \(0, 1\) 向量的集合 \(s\),使得 \(\forall \overrightarrow{v} \in s\),不存在 \(p_1, p_2 \cdots p_k(\overrightarrow{v_{p_i}} \ne \overrightarrow{v})\),使得 \(\oplus_{1 \le i \le k}\overrightarrow{v_{p_i}} = \overrightarrow v\)

线性基可以类比于平面向量中的基底。类比向量,线性基中的向量也可以说他们线性无关

  • 怎么求线性基

将线性基们排成矩阵。对矩阵做初等行列变换后得到的仍然是一组线性基。

因此可以将所有初始向量扔到矩阵里,然后进行初等行列变换削成下三角矩阵。根据高斯消元的过程可以发现,线性基的最高位 \(1\) 位置互不相同。因此最后消到为 \(0\) 的时候,前面 \(> 0\) 的就是线性基。

由此也可以发现线性基大小不超过 \(\log w\)

这个玩意有两种写法。第一种是用上面初等行列变换的思路:

rep(i, 1, n) {
        rep(j, i + 1, n)
            if (a[j] > a[i]) swap(a[i], a[j]);
        if (!a[i]) break;
        dep(j, 63, 0) if ((a[i] >> j) & 1) {
            rep(k, 1, n) if (k != i and ((a[k] >> j) & 1)) 
                a[k] ^= a[i];
            break;
        } Base.push_back(a[i]);
	}

第二种是基于插入的实现:

auto ins = [&](int x) {
    for (auto i : Base) x = min(x, i ^ x);
    if (x) Base.push_back(x);
};
rep(i, 1, n) ins(a[i]);

我个人偏向于前一种写法,因为它快得多。

posted @ 2024-11-28 21:01  Link-Cut-Y  阅读(1)  评论(0编辑  收藏  举报