线性基求交与求并

说明

先说明一下这里的求交与求并分别是什么意思。就是有两个线性空间V1V_1V1V2V_2V2,求出这两个空间的交与并。当然OI中的线性空间大部分是指异或操作下的,也就是常说的线性基。
如下所说的,都是异或的线性基,不区分加号与异或,即∑xi=x1⊕x2...⊕x3\sum x_i = x_1 \oplus x_2 ... \oplus x_3xi=x1x2...x3
当然可以扩展到任意线性空间,大致方法不变。

求交

明显答案也是一个线性基。
那么我们还需要如下引理:
{αi=1−x}\{\alpha_{i= 1 - x}\}{αi=1x}V1V_1V1的一组线性基,{βi=1−y}\{\beta_{i= 1 - y}\}{βi=1y}V2V_2V2的一组线性基。设WWW{β}\{\beta\}{β}中在V1V_1V1的基,如果α⋃{β∖W}\alpha \bigcup\{\beta \setminus{W}\}α{βW}线性无关,那么WWW就是交的线性基。
从而可以得到:

如果βi\beta_iβi能被{αi=1−x}\{\alpha_{i=1-x}\}{αi=1x}βj=1...i−1\beta_{j = 1 ... i - 1}βj=1...i1线性表示出来,我们可以把⨁i=1xαi\bigoplus_{i = 1}^{x}\alpha_ii=1xαi或者⨁j=1i−1βj\bigoplus_{j=1}^{i-1}\beta_jj=1i1βj(注意要么加入α\alphaα要么加入β\betaβ)加入答案的线性基中。
代码如下:

LinearBasis Merge(LinearBasis A,LinearBasis B) {
	LinearBasis All , C , D;
	All.clear();
	C.clear();
	D.clear();
	for (int i = 60;i >= 0;i--) {
		All.basis[i] = A.basis[i];
		D.basis[i] = 1ll << i;
	}
	for (int i = 60; i >= 0; i--) {
		if (B.basis[i]) {
			ll v = B.basis[i] , k = 0;
			bool can = true;
			for (int j = 60; j >= 0; j--) {
				if (v & (1ll << j)) {
					if (All.basis[j]) {
						v ^= All.basis[j];
						k ^= D.basis[j];
					} else {
						can = false;
						All.basis[j] = v;
						D.basis[j] = k;
						break;
					}
				}
			}

			if (can) {
				ll v = 0;
				for (int j = 60; j >= 0; j--) {
					if (k & (1ll << j)) {
						v ^= A.basis[j];
					}
				}
				C.insert(v);
			}
		}
	}
	C.build();
	return C;
}

同样的,如下代码也可以:

LinearBasis Merge(LinearBasis A,LinearBasis B) {
	LinearBasis All , C , D;
	All.clear();
	C.clear();
	D.clear();
	for (int i = 60;i >= 0;i--) All.basis[i] = A.basis[i];
	
	for (int i = 60; i >= 0; i--) {
		if (B.basis[i]) {
			ll v = B.basis[i] , k = 1ll << i;
			bool can = true;
			for (int j = 60; j >= 0; j--) {
				if (v & (1ll << j)) {
					if (All.basis[j]) {
						v ^= All.basis[j];
						k ^= D.basis[j];
					} else {
						can = false;
						All.basis[j] = v;
						D.basis[j] = k;
						break;
					}
				}
			}

			if (can) {
				ll v = 0;
				for (int j = 60; j >= 0; j--) {
					if (k & (1ll << j)) {
						v ^= B.basis[j];
					}
				}
				C.insert(v);
			}
		}
	}
	C.build();
	return C;
}

注意区别。

求并

通过容斥原理将并转化为交即可。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值