线性基小记

设有数集 \(S\),数的二进制表示最高位不超过 \(K\).可构造线性基为一最小化的集合 \(V\),满足一个数能被表示成若干 \(S\) 中的数的异或和,当且仅当其能被表示成若干个 \(V\) 中的数的异或和.\(V\) 的大小不超过 \(K+1\)

1 构造方法.

\(V_i\) 表示线性基中最高位为 \(i\) 的元素.考虑现在插入一个数 \(a\).从大到小枚举 \(i\).若 \(a\) 在第 \(i\) 位为 \(0\),则跳过;否则若不存在 \(V_i\),将 \(a\) 作为 \(V_i\) 并中断枚举,若存在 \(V_i\),将 \(a\) 变为 \(a\oplus V_i\) 并继续枚举.

性质的证明.

(一)一个数能被表示成若干 \(S\) 中的数的异或和,当且仅当其能被表示成若干个 \(V\) 中的数的异或和.

归纳证明.设原来的线性基满足性质.考虑在插入 \(a\) 后,一个被 \(S\) 中元素表示的数 \(\displaystyle x=a_{i_1} \oplus a_{i_2} \oplus...\oplus a_{i_k}\oplus a\)
我们做如下分类:

  • \(a\) 最终没有被插入线性基,则 a 可以被线性基中原来的元素表示出.\(\displaystyle x=a_{i_1} \oplus a_{i_2} \oplus...\oplus a_{i_k}\oplus a_{j_1} \oplus a_{j_2} \oplus...\oplus a_{j_{k^{'}}}\).显然可以被原来的线性基表示出.
  • \(a\) 被插入了线性基,设其为 \(V_a\).则有
    \(V_a=a \oplus a_{j_1} \oplus a_{j_2} \oplus...\oplus a_{j_{k^{'}}}\)
    \(a=V_a \oplus a_{j_1} \oplus a_{j_2} \oplus...\oplus a_{j_{k^{'}}}\)
    \(x=a_{i_1} \oplus a_{i_2} \oplus...\oplus a_{i_k}\oplus a\)
    \(\;\;\;=V_a \oplus a_{j_1} \oplus a_{j_2} \oplus...\oplus a_{j_{k^{'}}} \oplus a_{i_1} \oplus a_{i_2} \oplus...\oplus a_{i_k}\)

这是 \(S \rightarrow V\) 的证明,同理也有 \(V \rightarrow S\) 的证明.

当然,可以用 线性代数 理解.我们将 \(S\) 中的数看作 \(K+1\) 维的向量.那么 \(S\) 可以看做一个向量空间.这样一个向量空间显然不超过 \(K+1\) 维(这个是性质二).然后我们发现 \(V\) 其实是维护了一组极小的线性无关向量构成的上三角矩阵.我们插入 \(a\) 的过程其实是对新矩阵做高斯消元.

(二)\(V\) 的大小不超过 \(k+1\)

这个就很显然了.就不证了.

(三)\(V\) 是极小的.

这个就不会证了,当然从 线性代数 的角度理解好像可以.

code.

struct linebase{
	int c[Bit+1];
	linebase(){memset(c, 0, sizeof(c));}
	void ins(int x){
		for(int i=Bit; ~i; i--){
			if((x>>i)&1){
				if(!c[i]){c[i]=x; break;}
				x^=c[i];
			}
		}
	}
};
posted @ 2023-07-13 23:57  ckain  阅读(24)  评论(1)    收藏  举报