版权声明:虽然是个蒟蒻但是转载还是要说一声的哟 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;
}