题解 | #歇#
还原魔方
https://ac.nowcoder.com/acm/contest/27740/A
通过题目可知,要求得到m
段区间^
并且&
起来最大,所以如果某一位有贡献,每一段的某一位都要有1
,所以我们可以从高往低考虑,我们假设答案为x,先假设这一位1可以,那么x+=1<<i,然后判断可以不可以,怎么判断呢,每^起来==res就让sum++,最后看^==0并且sum>=m&&(sum-m)%2==0,就可以,具体实现可以看代码
/*made in mrd*/
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
#define endl '\n'
#define int long long
#define mem(a,b) memset(a,b,sizeof a)
#define fi first
#define se second
#define lu u<<1
#define ru u<<1|1
#define pb push_back
#define bug1(x) cout<<x<<endl
#define bug2(x,y) cout<<x<<' '<<y<<endl
#define pii pair<int,int>
#define bug3(x,y,z) cout<<x<<' '<<y<<' '<<z<<endl
void init()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
}
int n,m;
int a[N];
int b[N];
signed main() {
init();
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
int res=0;
for(int i=30;i>=0;i--)
{
res+=(1<<i);
for(int j=1;j<=n;j++)
{
b[j]=a[j]&res;
}
int sum=0;
int cnt=0;
for(int j=1;j<=n;j++)
{
sum^=b[j];
if(sum==res) sum=0,cnt++;
}
if(sum==0&&cnt>=m&&(cnt-m)%2==0);
else res-=(1<<i);
}
cout<<res<<endl;
return 0;
}