对于第i位 只有每段第i位都为0 结果才为0 所以要最小的话 从最高位开始判断是否可以为零 具体的求出前缀xor的值 如果第i位偶数个1 那就可以偶数个分一组 这样最后or的结果是0 在奇数个的位置打上标记 即不能在这里分开(这里分开的话or下来肯定是1) 扫完一遍如果 总标记+m-1<=n 那就有分成m段的方案 每一位这样贪心就能得到最小值
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=500010;
int n,m,sum,tot;
ll ans,v[maxn];
int s[maxn];
inline ll read()
{
ll 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;
}
int main()
{
n=read(),m=read();
int i,flag=0;
ll j;
for(i=1;i<=n;i++) v[i]=read();
for(j=1ll<<62;j;j>>=1)
{
for(sum=0,i=1;i<=n;i++) if(v[i]&j) sum++;
if(sum&1) ans^=j;
else
{
for(flag=sum=0,i=1;i<n;i++)
{
if(v[i]&j) flag^=1;
s[i]+=flag,sum+=(s[i]==1)&flag;
}
if(sum+tot+m>n)
{
ans^=j;
for(flag=sum=0,i=1;i<n;i++)
{
if(v[i]&j) flag^=1;
s[i]-=flag;
}
}
else tot+=sum;
}
}
cout<<ans<<endl;
}