1. 程式人生 > >[洛谷3812]【模板】線性基

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

ons int() 方法 algorithm 每一個 枚舉 nbsp max tchar

題目大意:
  給你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\n",ans); 33 return 0; 34 }

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