您的位置:首页 > 其它

[洛谷3812]【模板】线性基

2017-11-09 09:26 274 查看

题目大意:
  给你n个数,求这些数能异或出的数的最大值。

思路:
  线性基模板。
  b中的数满足对于每个b[i],最高位在第i位。
  构造方法就是对于每个数字,从高到低枚举每一个1,如果这一位对应的b[i]还没有,就把这个数作为b[i],如果有,就把这个数异或上b[i]。
  考虑两个数a,b,它们能异或出来的数为0,a,b,a xor b,如果把b换成a xor b,它们能异或出来的数还是0,a,b,a xor b。
  所以b能异或出来的值域和a能异或出来的值域相同。
  最后能异或出的最大值可以用类似贪心的思想。
  从高到低枚举每个数,如果和现在的ans异或起来比ans大那么就异或,不然就不管。
  这样就能优先保证更高的位出现在答案中,也就可以保证ans最大。

#include<cstdio>
#include<cctype>
#include<algorithm>
typedef long long int64;
inline int64 getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int64 x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
const int N=51;
int64 b
;
int main() {
const int n=getint();
for(register int i=0;i<n;i++) {
int64 x=getint();
for(register int i=N-1;~i;i--) {
if(!(x&(1ll<<i))) continue;
if(!b[i]) {
b[i]=x;
break;
} else {
x^=b[i];
}
}
}
int64 ans=0;
for(register int i=N-1;~i;i--) {
ans=std::max(ans,ans^b[i]);
}
printf("%lld\n",ans);
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: