[Notes&Record] 线性基计数入门
坑先开在这儿,但相关的题目还没刷两道。
虽然前面有一大堆关于异或线性基的废话,但重点还是计数。
基本概念
线性组合与张成空间
线性组合:对于向量组 \(V=\{\vec{v_i}\}_{i=1}^{n}\),若存在 \(c_1,c_2,\dots,c_n\in\mathbb{R}\),满足向量 \(\vec{a}=\sum_{i=1}^{n}c_i\vec{v_i}\),则称 \(\vec{a}\) 是 \(V\) 以 \(\{c_i\}_{i=1}^{n}\) 为系数的线性组合。
张成空间:对于向量组 \(V=\{\vec{v_i}\}_{i=1}^{n}\),其所有线性组合构成的集合称作 \(V\) 的张成空间,记作 \(\text{span}(V)\)。
线性相关与线性基
线性相关:对于向量组 \(V=\{\vec{v_i}\}_{i=1}^{n}\),若存在 \(c_1,c_2,\dots,c_n\in\mathbb{R}\) 且 \(\exists\ i,c_i\not=0\),使得 \(\sum_{i=1}^{n}c_i\vec{v_i}=0\),则称向量组 \(V\) 线性相关。
基:若向量组 \(B\) 线性无关,则称 \(B\) 为其张成空间 \(\text{span}(B)\) 的一组基。
- \(B\) 的任意真子集不是 \(\text{span}(B)\) 的基。
- 对于任意 \(\vec{v}\in\text{span}(B)\),存在唯一一组 \(c_1,c_2,\dots,c_n\in\mathbb{R}\),满足 \(\vec{v}\) 是 \(B\) 以 \(\{c_i\}_{i=1}^{n}\) 为系数的线性组合。
- 对于任意线性有关集 \(V\),存在其真子集 \(B\subset V\) 满足 \(\text{span}(B)=\text{span}(V)\)。
- 同一线性空间可能存在多组基。
异或线性基
异或线性基:\(\mathbb{F}_{2}^{n}\) 空间的一个 \(k\) 维子空间的基。
基本运算:\(\bmod 2\) 意义下加法等价于异或运算。
* 矩阵乘法的线性代数意义
矩阵乘法 \(A\cdot B=C\) 的线性代数意义:
- 列向量视角:\(A\) 的行向量与 \(B\) 的列向量的点积。
- 行向量视角:\(B\) 的行向量以 \(A\) 的列向量作为系数时的线性组合。
异或线性基相关操作
构造
贪心法
直接通过代码描述:
LL b[65];
void insert(LL x) {
for (int i = 60; i >= 0; i--) {
if ((x>>i)&1) {
if (b[i]) x ^= b[i];
else {
b[i] = x; break;
}
}
}
}
高斯消元法
显然对矩阵进行高斯消元,得到阶梯型矩阵,其中非全 \(0\) 的行向量构成的向量组即为一组异或线性基。
int Gauss(int n) {
int i, j;
for (i = 1, j = 1; i <= n && j <= n; j++) {
int r = i;
for (int k = i+1; k <= n; k++) {
if (C[k][j]) r = k;
}
if (!C[r][j]) continue;
if (r != i) swap(C[i], C[r]);
for (int k = i+1; k <= n; k++) {
int s = C[k][j];
if (s) C[k] ^= C[i];
}
++i;
}
return i-1;
}
代码中的返回值为线性基大小。
标准基(最简线性基)
将原本求解出的线性基(形如阶梯矩阵)消为最简即可。若通过高斯消元法求解线性基,在构造时选择高斯约旦消元法可以直接算出最简线性基。
int Gauss(int n) {
int i, j;
for (i = 1, j = 1; i <= n && j <= n; j++) {
int r = i;
for (int k = i+1; k <= n; k++) {
if (C[k][j]) r = k;
}
if (!C[r][j]) continue;
if (r != i) swap(C[i], C[r]);
for (int k = 1; k <= n; k++) {
int s = C[k][j];
if (s && k != i) C[k] ^= C[i];
}
++i;
}
return i-1;
}
第 k 小异或和
\(\text{rank}\) 从 \(0\) 开始计算。
设当前最简线性基为 \(B=\{\vec{b_i}\}_{i=0}^{n-1}\)(从小到大排序),则第 \(k\) 小异或和为 \(\vec{v}=\sum_{i=0}^{n-1}((k>>i)\&1)\cdot\vec{b_i}\)。
显然,最大异或和即为线性基中所有元素的异或和。
带删除线性基
显然只能使用贪心法构造,可以离线处理或增加贪心决策。
离线处理不必多提,后者可以求出每个元素的删除时间 \(t_i\),按加入时间依次插入线性基,存储 \((\vec{b_i},t_i)\) 的二元组,若当前第 \(i\) 位上有值 \((\vec{b_i},t_i)\) 且其删除时间早于插入二元组 \((\vec{b_j},t_j)\),则将两二元组 \(\text{swap}\) 互换再继续插入线性基。
线性基计数
* 常用结论
结论一:\(\mathbb{F}_{p}^{n}\) 中选出大小为 \(k\) 的线性无关向量组的方案数:\(\prod_{i=0}^{k-1}(p^n-p^i)\)。
- 组合意义:\(p^n\) 为向量空间 \(\mathbb{F}_{p}^{n}\) 的大小,\(p^i\) 为已经确定的前 \(i\) 个向量构成的集合的张成空间大小,两者相减即为当前可选方案数量。
结论二:\(\mathbb{F}_{p}^{n}\) 中本质不同 \(k\) 维子空间的数量:\(\dfrac{\prod_{i=0}^{k-1}(p^n-p^i)}{\prod_{i=0}^{k-1}(p^k-p^i)}\)。
结论三:\(\mathbb{F}_{p}\) 中秩为 \(k\) 的 \(n\times m\) 矩阵数量:\(\dfrac{\prod_{i=0}^{k-1}(p^n-p^i)(p^m-p^i)}{\prod_{i=0}^{k-1}(p^k-p^i)}\)。
* 方法总结
- 对张成空间计数,采用最简线性基与之形成双射。
- 绝大部分的线性基计数题目本质上是数位 dp。
题目
「NOI模拟」海象
矩阵乘法不便于计数,考虑通过矩阵的线性代数意义,将 \(A\) 视作对 \(B\) 做线性组合的系数,转换为对线性基的计数,此时问题与 \(A\) 的线性基无关,只与 \(B,C\) 的线性基有关。
考虑分步计算:
- 步骤一:求出在 \(C\) 矩阵的约束下,\(B\) 矩阵的线性基为某大小时的最简线性基数量。
- 步骤二:求出 \(B\) 矩阵的线性基为某大小时,一个线性基可能对应的矩阵数量。
- 步骤三:求出 \(B,C\) 确定且 \(B\) 的线性基为某大小时,\(A\) 可能的情况数量。
由于对线性基的讨论与对高斯消元后的主元的讨论等价,因此接下来从主元的角度描述。
首先需要高斯消元得到 \(C\) 矩阵的主元,设 \(C\) 的主元数量为 \(x\)。
步骤一:
由于 \(C\) 由 \(B\) 做线性组合得到,因此 \(C\) 的主元为 \(B\) 主元的子集,也就是说在动态规划的过程中,只用考虑 \(B\) 对 \(C\) 中非主元的选择情况即可。
设 \(g_{i,j}\) 表示考虑了 \(C\) 的前 \(i\) 个非主元,其中 \(j\) 个为 \(B\) 的主元,显然有转移 \(g_{i,j}=g_{i-1,j}+2^{i-j}\cdot g_{i-1,j-1}\),其中 \(2^{i-j}\) 表示非主元所在的列可以任取 \(0/1\)。
步骤二:
处理 \(g\) 之后枚举 \(k\) 表示 \(B\) 不在 \(C\) 主元集合中的主元数量,因此 \(B\) 中主元数量即为 \(x+k\)。在枚举以上信息的情况下,设 \(f_{i,j}\) 表示考虑到 \(B\) 矩阵的前 \(i\) 行,当前主元数量为 \(j\) 的情况数量,可以得到转移 \(f_{i,j}=2^j\cdot f_{i-1,j}+(2^{x+k}-2^{j-1})\cdot f_{i-1,j-1}\),组合意义与前文中常用结论一类似。
步骤三:
对于 \(B\) 中的主元,由于其需要通过线性变换对应到 \(C\) 中的主元或称为非主元,因此作为线性组合系数的矩阵 \(A\) 对应的列向量的值应当是确定的。而其他列由于对应 \(B\) 中的行向量并非主元,因此可以任取。所以若 \(B\) 中主元数量为 \(x+k\) 且此时 \(B,C\) 均已确定,\(A\) 可能的情况数量为 \(2^{n(n-x-k)}\) 种。
答案:
时间复杂度:\(O(n^3)\)。需要优化。
优化:
考虑到 \(f\) 的转移系数只与 \(k,j\) 有关,与 \(i\) 无关,且只有 \(j\) 需要加 \(1\) 的时候会乘上该系数,dp 转移类似于走网格图,所有路径都乘上的系数均相同,因此可以将 \((2^{x+k}-2^{j-1})\) 这一系数作为公因式提出,将 \(f\) 的转移改为 \(f_{i,j}=2^j\cdot f_{i-1,j}+f_{i-1,j-1}\),此时由于不需要 \(k\) 参与运算可以直接 \(O(n)\) 处理,计算答案时再枚举 \(k\) 将公因式乘回,即:
高斯消元通过 bitset 优化,时间复杂度:\(O(\dfrac{n^3}{\omega}+n^2)\)。
Fox and Perfect Sets
前置结论:最大异或和为线性基中所有元素的异或和。
对满足空间内任意元素不超过 \(n\) 的张成空间计数,考虑转换为其双射,对最简线性基进行数位 dp,设 \(f_{i,j,k}\)(\(0\leq i,j\leq 30,k\in\{0,1\}\))表示当前从高到低考虑到线性基的第 \(i\) 位(即线性基内所有元素从最高位到第 \(i\) 位均已确定),其中已经填了 \(j\) 个主元,当前异或最大值加 \(2^{i}\) 是否大于 \(n\)(即前 \(i\) 位是否均已抵满上界)。
由于当前是最简线性基,因此当考虑到某一位需要填数时,前面已确定的主元行这一位必须为 \(0\),否则前面已确定的主元行这一位可以根据要求任填 \(0/1\)。
由于已经考虑了的某一位上填 \(1\) 的主元行数量奇偶性可能影响答案,因此设:
接下来分类讨论转移。
对于 \(k=0\),此时第 \(i-1\) 位填和不填都不会再抵满 \(n\):
- 填:\(f_{i,j,0}\rightarrow f_{i-1,j+1,0}\)。
- 不填:\(2^{j}\cdot f_{i,j,0}\rightarrow f_{i-1,j,0}\)。
对于 \(k=1\),此时需要看 \(n\) 的第 \(i-1\) 位是 \(0\) 还是 \(1\):
- 第 \(i-1\) 位为 \(0\):不能填,且已确定的 \(j\) 个主元行该位为 \(1\) 的数量必须为偶数,因此转移为 \(cnt_{j,0}\cdot f_{i,j,1}\rightarrow f_{i-1,j,0}\)。
- 第 \(i-1\) 位为 \(1\):可填可不填,且需讨论前 \(j\) 个主元行该位为 \(1\) 的数量奇偶性:
- 填:\(f_{i,j,1}\rightarrow f_{i-1,j+1,1}\)。
- 不填且前 \(j\) 个主元行该位有偶数个 \(1\):此时这一位的异或和为 \(0\),没有抵满,因此转移为 \(cnt_{j,0}\cdot f_{i,j,1}\rightarrow f_{i-1,j,0}\)。
- 不填且前 \(j\) 个主元行该位有奇数个 \(1\):此时这一位的异或和为 \(1\),依然抵满,因此转移为 \(cnt_{j,1}\cdot f_{i,j,1}\rightarrow f_{i-1,j,1}\)。
October 18, 2017
当 \(x=0\) 时,相当于在线性空间中选出 \(n\) 个向量构成的线性无关组,故而答案为 \(\prod_{i=0}^{n-1}(2^k-2^i)\)。
当 \(x\not= 0\) 时,容易发现 \(x\) 具体为什么值对答案不产生影响。
前置结论:
- 若 \(V\) 是 \(\mathbb{F}_q\) 上的 \(n\) 维线性空间,则 \(V\) 有 \(\dfrac{q^n-1}{q-1}\) 个 \(n-1\) 维线性子空间。
- 若 \(V\) 是 \(\mathbb{F}_q\) 上的 \(n\) 维线性空间,\(\vec{x}\in V\backslash\{0\}\),则 \(V\) 有 \(\dfrac{q^{n-1}-1}{q-1}\) 个线性子空间包含 \(\vec{x}\)。
假设向量 \(x\) 恰在 \(k-i\) 维度空间内被舍弃,因而会进行 \(i\) 次降维,在前 \(i-1\) 次降维中强制保留 \(x\),则方案数量为 \(\prod_{j=1}^{i-1}(2^{k-j}-1)\),在第 \(i\) 次降维中需舍弃 \(x\),方案数量为 \(2^{k-i}\) 种,此时 \(a\) 中每一元素均可在这个 \(k-i\) 维子空间内任取,方案数量为 \((2^{k-i})^n\) 种。
也就是说,统计形如 \((S_0,S_1,\dots,S_{i-1},S_i,a)\) 的多元组数量,满足:
- \(S_0\) 为原问题空间 \(\mathbb{F}_{2}^{k}\)。
- \(S_j(1\leq j<i)\) 为 \(S_{j-1}\) 包含向量 \(x\) 的 \(k-j\) 维子空间。
- \(S_i\) 为 \(S_{i-1}\) 不包含向量 \(x\) 的 \(k-i\) 维子空间。
- \(a\) 为 \(S_i\) 中任意包含 \(n\) 个向量的向量组。
由于 \(a\) 任取时,\(a\) 的张成空间可能低于 \(k-i\) 维,因此会算重,需要通过容斥处理。
综上,答案式如下(累乘符号下标大于上标时值视为 \(1\)):
因为要刨除向量 \(x\) 至少需要丢弃一个维度,因此求和下标从 \(1\) 开始。
考虑证明以上容斥恰好将每个向量组 \(a\) 计算到一次,也就是说,每个 \(a\) 在如上容斥式子中对应的系数恰好为 \(1\)。由于 \(a\) 在以上式子中哪些会被统计到与其张成空间有关,因而设 \(a\) 的张成空间为 \(T\),其大小为 \(t\),此时计算上述多元组 \((S_0,S_1,\dots,S_{i-1},S_i,a)\) 数量乘容斥系数后的和。
经过尝试发现,直接通过 \(T\) 计算以上空间组依然是不便的,故而考虑转换为对正交补空间进行统计,可以发现,原多元组 \((S_0,S_1,\dots,S_{i-1},S_i,a)\) 与满足如下条件的多元组 \((S'_0,S'_1,\dots,S'_{i-1},S'_{i},T)\) 形成双射:
- \(S'_0\) 为与 \(T\) 正交的 \(k-t\) 维线性空间。
- \(S'_j(1\leq j<i)\) 为 \(S_{j-1}\) 包含向量 \(x\) 的 \(k-t-j\) 维子空间。
- \(S'_i\) 为 \(S'_{i-1}\) 不包含向量 \(x\) 的 \(k-t-i\) 维子空间。
当正交补空间包含向量 \(x\) 时,原空间不包含 \(x\),因此将正交补空间对应回原空间,这个序列相当于反向考虑升维过程,枚举在哪个维度向量 \(x\) 被加入线性空间。
此时多元组数量的统计与前文是相同的,乘上前文统计时的容斥系数,因此只需证明以下式子成立(累乘符号下标大于上标时值视为 \(1\)):
\(k-t=1\) 时,结论显然成立;当 \(k-t>1\) 时,采用数学归纳法,将 \(i=1\) 一项拆出并移项到式子右侧,有:
左右两侧同时除以 \((1-2^{k-t-1})\) 得:
下标化为 \(1\) 得:
此时式子即为上界为 \(k-t-1\) 时的原式形式,归纳得出结论成立。
永恒(Eternity)
相对还是比较简单和套路,将问题拆分为两个部分:
- 对于 \(1\leq k\leq 60\) 的所有 \(k\) 求出满足 \(\oplus_{i=1}^{k}b_i=m\) 的线性基 \(B=\{b_i\}_{i=1}^{k}\) 个数。
- 对于 \(1\leq k\leq 60\) 的所有 \(k\) 求出大小为 \(k\) 的线性基对应的大小为 \(n\) 的可重集合 \(S=\{a_i\}_{i=1}^{n}\) 个数。
两个部分相乘即为答案。
第一部分的求解与 Fox and Perfect Sets 一题相同,不再作过多赘述。
对于第二部分,设 \(g_i\) 为大小为 \(i\) 的线性基对应的可重集数量。首先可以朴素地考虑从线性空间中可重复地选取 \(n\) 个元素的方案数量,即 \(\binom{2^{i}+n-1}{n}\) 种。显然这样会导致选取出的元素的张成空间维度可能小于 \(i\),因此考虑减法原理去除这一部分。
令 \(h_{i,j}\) 表示从大小为 \(i\) 的线性基删除 \(j\) 个向量后可以得到的不同子基数量,则有:
对于 \(h\) 的计算,容易列出转移方程:
即考虑到原线性基第 \(i\) 个向量时,该元素如果删除,此时由 \(h_{i-1,j-1}\) 直接转移;如果不删除,这个向量可以任意异或上之前删除掉的向量,因此乘上系数 \(2^j\)。
综上,答案为:
Many Xor Optimization Problems
显然我是不可能很会的(逃)。
欸?我好像会了,工作日写了代码来补一下。(周天坚决不写代码!)
2025.07.14 upd: 我想的东西貌似是只能优化到 \(O(n^2)\) 的。
【10.14NOIP模拟】AND 和 XOR
设 \(f_{s,t,0/1}\) 为在所有满足 \(a_i\text{ and }s=s\) 的 \(i\) 中选取偶数/奇数个数,得到的 \(\text{xor}\) 和为 \(t\) 的方案数量。
若 \(s\not=0\),选取奇数个满足 \(a_i\text{ and }s=s\) 的数,它们 \(\text{xor}\) 和恰等于 \(s\),则 \(\text{and}\) 和也等于 \(s\)。
但对于 \(s=0\) 的情况而言,\(a_i\text{ and }s=s\) 相当于没有对 \(a_i\) 进行任何限制。同样可以发现,\(f_{s,t,0}\) 表示的应为在选取偶数个数,\(\text{xor}\) 和等于 \(t\) 的情况下,\(\text{ and }\) 和至少包含 \(s\) 中为 \(1\) 的位,此时的方案数。
因此使用超集反演,两部分答案的总和为:
因为选取个数为偶数时包含选择空集的情况,因此减去 \(1\)。
设可选取的位置集合为 \(\{p\}_{i=1}^{k}\),选择情况的布尔变量为 \(\{b\}_{i=1}^k\),以 \(f_{s,s,0}\) 为例,列出线性方程组:
方程有解时,设自由变元个数为 \(cnt\),有 \(f_{s,s,1}=2^{cnt}\)。同理可以处理 \(f_{s,s,0}\)。
自由变元个数可以通过线性基快速计算。
枚举 \(s\) 和合法的 \(a_i\) 插入线性基的复杂度不够优秀,设 \(f_{s,s,1}\) 对应的线性基为 \(B_s\),考虑如下事实:
- 若 \(s\subseteq t\),则 \(\text{span}(B(t))\subseteq\text{span}(B(s))\)。
因此可以使用高维后缀和合并来求出所有 \(s\) 对应的线性基。
时间复杂度 \(O(nm+2^mm^3)\)。

浙公网安备 33010602011771号