bzoj4269 再见Xor 线性基

版权声明:虽然是个蒟蒻但是转载还是要说一声的哟 https://blog.csdn.net/jpwang8/article/details/85268095

Description


给定N个数,你可以在这些数中任意选一些数出来,每个数可以选任意多次,试求出你能选出的数的异或和的最大值和严格次大值。

100% : N <= 100000, 保证N个数不全是0,而且在int范围内

Solution


线性基应用。。
我们求出线性基然后直接最大值。次大值就用最大值异或最小位上的基即可

这里记一下线性基的两个小性质。
若基的数量为n,则可以表达的数有2n
线性基求第k小,把k二进制拆分然后把1的位上的基异或起来就可以了

Code


#include <stdio.h>
#include <string.h>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define drp(i,st,ed) for (int i=st;i>=ed;--i)

const int N=200005;

struct Gay {
	int r[31];
	void ins(int x) {
		drp(i,30,0) if ((x>>i)&1) {
			if (!r[i]) {
				r[i]=x;
				return ;
			}
			x^=r[i];
		}
	}
	void get_max() {
		int res=0;
		drp(i,30,0) if ((res^r[i])>res) res^=r[i];
		printf("%d ", res);
		rep(i,0,30) if ((res^r[i])<res) {
			printf("%d\n", res^r[i]);
			return ;
		}
	}
} G;

int read() {
	int x=0,v=1; char ch=getchar();
	for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar());
	for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());
	return x*v;
}

int main(void) {
	int n=read();
	rep(i,1,n) {
		int x=read();
		G.ins(x);
	}
	G.get_max();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/jpwang8/article/details/85268095