分析:
本校OI组交流时讲到的一道题,这道题很好地利用到了或与异或的性质。
按照按位贪心的思想从高位到低位贪心,发现只要有不少于m处的前缀异或和在该位为0,并且整个数列的异或和在该位也为0,那么这位就可以取到0。
为了不出现选取在更高位上不合法的位置划分,每处理完一位就把该位的前缀异或和改为(unsigned long long)-1(类似于打标记,不用更新之后的前缀异或和)。
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
typedef unsigned long long LL;
inline LL read(){
LL x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
const int MAXN=500005;
int n,m;
LL a[MAXN],xsum[MAXN];
int main(){
n=read(),m=read();LL ans=0;
for(int i=1;i<=n;i++) xsum[i]=xsum[i-1]^(a[i]=read());
for(int i=63;i+1;i--){
int temp=0;
for(int j=1;j<=n;j++)
if(!((xsum[j]>>i)&1)) temp++;
if(!((xsum[n]>>i)&1)&&temp>=m)
{for(int j=1;j<=n;j++) if((xsum[j]>>i)&1) xsum[j]=-1;}
else ans|=((LL)1<<i);
}
printf("%llu\n",ans);
return 0;
}