设有数集 SSS,数的二进制表示最高位不超过 KKK.可构造线性基为一最小化的集合 VVV,满足一个数能被表示成若干 SSS 中的数的异或和,当且仅当其能被表示成若干个 VVV 中的数的异或和.VVV 的大小不超过 K+1K+1K+1.
1 构造方法.
记 ViV_iVi 表示线性基中最高位为 iii 的元素.考虑现在插入一个数 aaa.从大到小枚举 iii.若 aaa 在第 iii 位为 000,则跳过;否则若不存在 ViV_iVi,将 aaa 作为 ViV_iVi 并中断枚举,若存在 ViV_iVi,将 aaa 变为 a⊕Via\oplus V_ia⊕Vi 并继续枚举.
性质的证明.
(一)一个数能被表示成若干 SSS 中的数的异或和,当且仅当其能被表示成若干个 VVV 中的数的异或和.
归纳证明.设原来的线性基满足性质.考虑在插入 aaa 后,一个被 SSS 中元素表示的数 x=ai1⊕ai2⊕...⊕aik⊕a\displaystyle x=a_{i_1} \oplus a_{i_2} \oplus...\oplus a_{i_k}\oplus ax=ai1⊕ai2⊕...⊕aik⊕a.
我们做如下分类:
- 若 aaa 最终没有被插入线性基,则 a 可以被线性基中原来的元素表示出.x=ai1⊕ai2⊕...⊕aik⊕aj1⊕aj2⊕...⊕ajk′\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^{'}}}x=ai1⊕ai2⊕...⊕aik⊕aj1⊕aj2⊕...⊕ajk′.显然可以被原来的线性基表示出.
- 若 aaa 被插入了线性基,设其为 VaV_aVa.则有
Va=a⊕aj1⊕aj2⊕...⊕ajk′V_a=a \oplus a_{j_1} \oplus a_{j_2} \oplus...\oplus a_{j_{k^{'}}}Va=a⊕aj1⊕aj2⊕...⊕ajk′
a=Va⊕aj1⊕aj2⊕...⊕ajk′a=V_a \oplus a_{j_1} \oplus a_{j_2} \oplus...\oplus a_{j_{k^{'}}}a=Va⊕aj1⊕aj2⊕...⊕ajk′
x=ai1⊕ai2⊕...⊕aik⊕ax=a_{i_1} \oplus a_{i_2} \oplus...\oplus a_{i_k}\oplus ax=ai1⊕ai2⊕...⊕aik⊕a
=Va⊕aj1⊕aj2⊕...⊕ajk′⊕ai1⊕ai2⊕...⊕aik\;\;\;=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}=Va⊕aj1⊕aj2⊕...⊕ajk′⊕ai1⊕ai2⊕...⊕aik
这是 S→VS \rightarrow VS→V 的证明,同理也有 V→SV \rightarrow SV→S 的证明.
当然,可以用 线性代数 理解.我们将 SSS 中的数看作 K+1K+1K+1 维的向量.那么 SSS 可以看做一个向量空间.这样一个向量空间显然不超过 K+1K+1K+1 维(这个是性质二).然后我们发现 VVV 其实是维护了一组极小的线性无关向量构成的上三角矩阵.我们插入 aaa 的过程其实是对新矩阵做高斯消元.
(二)VVV 的大小不超过 k+1k+1k+1.
这个就很显然了.就不证了.
(三)VVV 是极小的.
这个就不会证了,当然从 线性代数 的角度理解好像可以.
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];
}
}
}
};