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

题目大意:
  给你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最大。

 1 #include<cstdio>
 2 #include<cctype>
 3 #include<algorithm>
 4 typedef long long int64;
 5 inline int64 getint() {
 6     register char ch;
 7     while(!isdigit(ch=getchar()));
 8     register int64 x=ch^'0';
 9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
10     return x;
11 }
12 const int N=51;
13 int64 b[N];
14 int main() {
15     const int n=getint();
16     for(register int i=0;i<n;i++) {
17         int64 x=getint();
18         for(register int i=N-1;~i;i--) {
19             if(!(x&(1ll<<i))) continue;
20             if(!b[i]) {
21                 b[i]=x;
22                 break;
23             } else {
24                 x^=b[i];
25             }
26         }
27     }
28     int64 ans=0;
29     for(register int i=N-1;~i;i--) {
30         ans=std::max(ans,ans^b[i]);
31     }
32     printf("%lld
",ans);
33     return 0;
34 }
原文地址:https://www.cnblogs.com/skylee03/p/7807815.html