题目大意:给定一个长度为n的序列,要求分成m段,使得每段异或和的或值最小
求出前缀异或和后从大到小按位确定,如果某一位上有至少m个数是0且第n个数是0,那么这一位就可以是0,同时将所有是1的数字标记为不可选
时间复杂度O(nlogai)
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 500500
using namespace std;
int n,m;
long long a[M],ans;
bool v[M];
int main()
{
int i;
long long j;
cin>>n>>m;
for(i=1;i<=n;i++)
scanf("%lld",&a[i]),a[i]^=a[i-1];
for(j=1ll<<62;j;j>>=1)
{
int cnt=0;
for(i=1;i<=n;i++)
if( !v[i] && ~a[i]&j )
++cnt;
if( cnt>=m && ~a[n]&j )
{
for(i=1;i<=n;i++)
if(a[i]&j)
v[i]=true;
}
else
ans|=j;
}
cout<<ans<<endl;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-12 04:49:56