BZOJ 4245: [ONTAK2015]OR-XOR|进制类|贪心

思路:见到二进制的题就想贪心,按位处理!

用了种合并的思想

如果最高位在分成m段及以上的情况下能为0,那么就让他为0

其实分成m段以上最高位能为0,那么分成m段最高位肯定能为0

然后就保证最高位为零的情况下,尽量分成更多的段,合并

然后以同样的思路处理下一位


#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<algorithm>
#include<iostream>
#define ll  long long
using namespace std;
ll sc()
{
	ll i=0; char c=getchar();
	while(c>'9'||c<'0') c=getchar();
	while(c>='0'&&c<='9') i=i*10+c-'0',c=getchar();
	return i;
}
ll a[505050],b[505050],ans;
int last[505050];
int n,m;
int main()
{
	n=sc(),m=sc();
	for(int i=1; i<=n; i++) a[i]=a[i-1]^sc();
	for(int i=62; i>=0; i--)
	{
		if(a[n]&((ll)1<<i)) continue;
		int tot=0;
		for(int j=1; j<=n; j++)
		    if((a[j]&((ll)1<<i))==0) tot++,last[tot]=j;
		if(tot<m) continue;
		for(int j=1; j<=tot; j++) a[j]=a[last[j]];
		//for(int j=1; j<=tot; j++) a[j]=b[j];
		n=tot;                  //n段合并为了tot段
	}
	for(int i=1; i<=n; i++) ans|=(a[i]^a[i-1]);
	cout << ans;
	return 0;
}
	
	
	
	
	
	



你可能感兴趣的:(贪心,进制类)