G64【模板】线性基+贪心法 P3812 最大异或和

视频链接:G64【模板】线性基 贪心法 P3812 最大异或和_哔哩哔哩_bilibili

 

 

 

P3812 【模板】线性基 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

// 线性基 O(63*n)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

typedef long long LL;
int n;
LL p[64];

void insert(LL x){ //贪心法
  for(int i=63;i>=0;--i){
    if(x>>i&1){  //x第i位为1
      if(!p[i]){ //不存在则加入
        p[i]=x; 
        break;
      }
      x^=p[i];   //存在则异或
    }
  }
}
int main(){
  scanf("%d",&n);
  for(int i=0;i<n;i++){
    LL x; scanf("%lld",&x);
    insert(x);
  }
  LL ans=0;
  for(int i=63;i>=0;i--) ans=max(ans,ans^p[i]);
  printf("%lld\n",ans);
}

 

// 线性基 O(63*n)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

typedef long long LL;
int n,k;
LL p[64];

void gauss(){ //高斯消元法
  for(int i=63;i>=0;i--){
    // 把当前第i位是1的数换上去
    for(int j=k;j<n;j++)
      if(p[j]>>i&1){swap(p[j],p[k]); break;}
    // 当前第i位所有向量都是0
    if((p[k]>>i&1)==0) continue;
    // 把其他数的第i位全部消为0
    for(int j=0;j<n;j++)
      if(j!=k&&(p[j]>>i&1)) p[j]^=p[k];
    // 基的个数+1
    k++; if(k==n) break;
  }
}
int main(){
  scanf("%d",&n);
  for(int i=0;i<n;i++)scanf("%lld",&p[i]);
  gauss();
  LL ans=0;
  for(int i=0;i<k;i++) ans^=p[i];
  printf("%lld\n",ans);
}

 

posted @ 2024-07-08 22:46  董晓  阅读(45)  评论(0编辑  收藏  举报