[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)}\) 种。

答案

\[ans=\sum_{k=0}^{n-x}2^{n(n-x-k)}\cdot f_{n,x+k}\cdot g_{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\) 将公因式乘回,即:

\[ans = \sum_{k=0}^{n-x}2^{n(n-x-k)}\cdot(\prod_{i=1}^{k}(2^{x+k}-2^{i-1}))\cdot f_{n,x+k}\cdot g_{n-x,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\) 的主元行数量奇偶性可能影响答案,因此设:

\[\begin{align*} cnt_{j,0}&=\sum_{i\mid i\bmod 2 = 0}\binom{j}{i}=2^{j-1}\\ cnt_{j,1}&=\sum_{i\mid i\bmod 2 = 1}\binom{j}{i}\\ &=\begin{cases}0 & (j=0),\\2^{j-1}&\text{otherwise}. \end{cases} \end{align*} \]

接下来分类讨论转移。

对于 \(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\)):

\[ans=\sum_{i=1}^{k}(-1)^{i-1}\cdot(2^{k-i})^n\cdot(2^{k-i}\cdot\prod_{j=1}^{i-1}(2^{k-j}-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\)):

\[\sum_{i=1}^{k-t}((-1)^{i-1}\cdot 2^{k-t-i}\cdot\prod_{j=1}^{i-1}(2^{k-t-j}-1))=1 \]

\(k-t=1\) 时,结论显然成立;当 \(k-t>1\) 时,采用数学归纳法,将 \(i=1\) 一项拆出并移项到式子右侧,有:

\[\sum_{i=2}^{k-t}((-1)^{i-1}\cdot 2^{k-t-i}\cdot\prod_{j=1}^{i-1}(2^{k-t-j}-1))=1-2^{k-t-1} \]

左右两侧同时除以 \((1-2^{k-t-1})\) 得:

\[\sum_{i=2}^{k-t}((-1)^i\cdot2^{k-t-i}\cdot\prod_{j=2}^{i-1}(2^{k-t-j}-1))=1 \]

下标化为 \(1\) 得:

\[\sum_{i=1}^{k-t-1}((-1)^{i-1}\cdot 2^{k-t-1-i}\cdot\prod_{j=1}^{i-1}(2^{k-t-1-j}-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\) 个向量后可以得到的不同子基数量,则有:

\[g_i=\binom{2^i+n-1}{n}-\sum_{j=1}^{i}h_{i,j}\cdot g_{i-j} \]

对于 \(h\) 的计算,容易列出转移方程:

\[h_{i,j}=h_{i-1,j-1}+2^j\cdot h_{i-1,j} \]

即考虑到原线性基第 \(i\) 个向量时,该元素如果删除,此时由 \(h_{i-1,j-1}\) 直接转移;如果不删除,这个向量可以任意异或上之前删除掉的向量,因此乘上系数 \(2^j\)

综上,答案为:

\[ans=\sum_{i=0}^{60}f_{0,i,1}\cdot g_i \]

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\) 的位,此时的方案数。

因此使用超集反演,两部分答案的总和为:

\[\sum_{i=1}^{2^m-1}(f_{s,s,1}+(-1)^{\text{popcount}(s)}(f_{s,s,0}-1)) \]

因为选取个数为偶数时包含选择空集的情况,因此减去 \(1\)

设可选取的位置集合为 \(\{p\}_{i=1}^{k}\),选择情况的布尔变量为 \(\{b\}_{i=1}^k\),以 \(f_{s,s,0}\) 为例,列出线性方程组:

\[\begin{cases} \oplus_{i=1}^{k}b_i=1\\ \oplus_{i=1}^{k}a_{p_i}^{(0)}b_i=s^{(0)}\\ \oplus_{i=1}^{k}a_{p_i}^{(1)}b_i=s^{(1)}\\ \dots\\ \oplus_{i=1}^{k}a_{p_i}^{(m-1)}b_i=s^{(m-1)} \end{cases} \]

方程有解时,设自由变元个数为 \(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)\)

posted @ 2025-07-08 16:25  剑履山河  阅读(41)  评论(0)    收藏  举报