[LOJ#6060][线性基]2017 山东一轮集训 Day1. Set

来源:互联网 发布:软件开发过程检测规范 编辑:程序博客网 时间:2024/06/04 19:30

学一发线性基
首先可以发现x1x2=xx为所有元素的异或和

单独考虑x的每一位,为0,则x1,x2这一位都是0或1,为1,则只有一位为1,刚开始打了个不动脑子的暴力竟然有70分……

考虑用线性基,因为要x1+x2最大,所以越高位的x的为0的位要优先确定,改变下贪心顺序求满足条件的最大的x2就可以了

#include <cstdio>#include <iostream>#include <algorithm>#include <set>using namespace std;const int N=100010;typedef long long ll;int n;ll ans,x,a[N];inline char nc(){  static char buf[100000],*p1=buf,*p2=buf;  return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}inline void rea(int &x){  char c=nc(); x=0;  for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());}inline void rea(ll &x){  char c=nc(); x=0;  for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());}struct LB{  ll a[65];  void insert(ll x,ll lim){    for(int i=60;~i;i--)      if((x>>i&1)&&!(lim>>i&1)){    if(a[i]) x^=a[i];    else{      a[i]=x; return;    }      }    for(int i=60;~i;i--)      if((x>>i&1)&&(lim>>i&1)){    if(a[i]) x^=a[i];    else{      a[i]=x; return ;    }      }  }  ll query(ll lim){    ll ret=0;    for(int i=60;~i;i--)      if(!(ret>>i&1)&&!(lim>>i&1)) ret^=a[i];    for(int i=60;~i;i--)      if(!(ret>>i&1)&&(lim>>i&1)) ret^=a[i];    return ret;  }}L;int main(){  rea(n);  for(int i=1;i<=n;i++) rea(a[i]),x^=a[i];  for(int i=1;i<=n;i++) L.insert(a[i],x);  printf("%lld\n",L.query(x)^x);  return 0;}
阅读全文
0 0
原创粉丝点击