线性基初步

大致思路

如果这n个数每个数的最高位的1的位置都不一样,我们就可以从高位向低位贪心选择取或者不取。

线性基就是把n个数选一些异或和出来化成这样一种情况:

对于当前这个数,选取它的最高位的1,看看线性基中有没有已经存入一个这样的数,如果没有存入,当然就把这个数存入,退出。

但是如果已经有了呢?可以发现线性基中存了的数一定是之前一些数的异或和,并且它的最高位的1也是同一位。那么我们把当前这个数异或上线性基存的这个数(显然结果还是一些数的异或和),自然这个最高位的1的位置就会变低,然后再丢回上一步重新考虑。

最后在贪心的取就行了。

代码(p3812

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
#define li long long
inline li read(){
      li x=0,f=1;char s=getchar();
      while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
      while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+(s-'0');s=getchar();}
      return x*f;
}
li belong[210000],x,n,i,j,k;
int main()
{     n=read();
      for(i=1;i<=n;i++){
          x=read();
          for(j=51;j>=0;j--)
             if(x&(1ll<<j)){
                  if(!belong[j]){
                      belong[j]=x;
                      break;
                  }
                  x^=belong[j];
             }
      }
      li ans=0;
      for(i=51;i>=0;i--)ans=max(ans,ans^belong[i]);
      printf("%lld\n",ans);
      return 0;
}

猜你喜欢

转载自www.cnblogs.com/yzxverygood/p/9178948.html