首先明确最后的结果运算下来只有一个数字,把他想象成二进制数的话,要使答案最小,就应该满足高位1竟可能的少用0来代替。维护一个异或前缀和,从高位开始枚举,当枚举的这一位为0的前缀和个数大于等于m且第n位也是0的时候当前位可以为0.然后标记所有的当前位为1的异或前缀在之后都不能划分
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define LL long long
#define maxn 500020
LL n,m,a[maxn];
bool vis[maxn];
int main(){
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++){
scanf("%lld",a+i);a[i]^=a[i-1];
}
LL ans=0;
for(LL i=1ll<<62;i;i>>=1){
int cnt=0;
for(int j=1;j<=n;j++)
if(!vis[j]&&(a[j]^i)&i)cnt++;
if(cnt>=m&&(a[n]^i)&i){
for(int j=1;j<=n;j++)
if(a[j]&i)vis[j]=true;
}
else ans|=i;
}
cout<<ans;
return 0;
}