题目大意
将
n
个数分成
N≤5×105,ai≤1018
Solution
这题好神呀。首先这种跟位运算有关的题目肯定是按位考虑的,那么我们从高位往低位贪心。判断每一位是否能取0时,采取下面的策略:
先计算前缀异或和。因为考虑到我们最后通过
or
统计答案,那么就要保证这
m
段在这一位异或必须为0,那么就是要在这些前缀异或和中能否找到
#include<set>
#include<map>
#include<queue>
#include<cmath>
#include<string>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define rep(i,a,b) for (int i=a; i<=b; i++)
#define per(i,a,b) for (int i=a; i>=b; i--)
using namespace std;
typedef long long LL;
inline int read() {
int x=0,f=1; char ch=getchar();
while (!(ch>='0'&&ch<='9')) {if (ch=='-')f=-1;ch=getchar();}
while (ch>='0'&&ch<='9') {x=x*10+(ch-'0'); ch=getchar();}
return x*f;
}
const int N = 500005;
int n,m;
LL a[N],ans=0;
bool ban[N];
int main() {
#ifndef ONLINE_JUDGE
// freopen("data.in","r",satdin);
// freopen("data.out","w",stdout);
#endif
n=read(),m=read();
rep(i,1,n) scanf("%lld",&a[i]);
rep(i,2,n) a[i]^=a[i-1];
per(i,62,0) {
int cnt=0;
rep(j,1,n) if (!ban[j]&&(a[j]&(1LL<<i))==0) cnt++;
if (cnt>=m&&(a[n]&(1LL<<i))==0) {
rep(j,1,n) if (a[j]&(1LL<<i)) ban[j]=1;
} else ans|=(1LL<<i);
}
printf("%lld\n",ans);
return 0;
}