题目大意:
给你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 }
时间: 2024-10-10 07:50:18