51nod1496最小异或和 乱搞

Description
一个集合包含一组相互不同的数字。现在我们要去寻找一个集合,他要满足如下性质:
对于所有 x(x∈S) ,要满足l ≤ x ≤ r;
1 ≤ |S| ≤ k;
设S中第i个元素是 si ;那么 f(S)=s1 ⨁ s2 ⨁ … ⨁ s|S| 的值要尽可能小。


Sample Input
8 15 3


Sample Output
1


这道题k=1,2,4的情况比较显然,k=3,你设r的从左往右第二个进制为z,t=(1<<(z+1))-1,若l<=t,则可用三个数合成:r,t,r^t


#include <cstdio>
#include <cstring>

using namespace std;
typedef long long LL;
LL _min(LL x, LL y) {return x < y ? x : y;}

LL bin[41];

int main() {
	LL l, r; int k;
	scanf("%lld%lld%d", &l, &r, &k);
	if(k == 1) printf("%lld\n", l);
	else if(k == 2) {
		if(r - l >= 2) printf("1\n");
		else if(r - l == 0) printf("%lld\n", l);
		else {
			LL u = l ^ r;
			if(u < l) printf("%lld\n", u);
			else printf("%lld\n", l);
		}
	} else if(k >= 4){
		if(r - l == 0) printf("%lld\n", l);
		else if(r - l == 1) {
			LL u = l ^ r;
			if(u < l) printf("%lld\n", u);
			else printf("%lld\n", l);
		} else if(r - l == 2){
			LL hh = _min(_min(l, l + 1), l + 2);
			hh = _min(hh, (l + 1) ^ l);
			hh = _min(hh, (l + 1) ^ r);
			hh = _min(hh, l ^ r);
			hh = _min(hh, l ^ (l + 1) ^ r);
			printf("%lld\n", hh);
		} else if(r - l == 3) {
			if(l % 2 == 0) printf("0\n");
			else {
				if(r <= 6) printf("0\n");
				else printf("1\n");
			}
		} else printf("0\n");
	} else {
		if(l == r) printf("%lld\n", l);
		else if(r - l == 1) {
			LL u = l ^ r;
			if(u < l) printf("%lld\n", u);
			else printf("%lld\n", l);
		} 
		else {
			int u = 0, p, o;
			bin[0] = 1; for(int i = 1; i <= 40; i++) bin[i] = bin[i - 1] * 2LL;
			for(int i = 40; i >= 0; i--) if(bin[i] <= r){
				if(u == 1) o = i;
				r -= bin[i], u++;
				p = i;
			} if(u == 1) {
				if(p == 2) {
					if(l == 2) printf("1\n");
					else printf("0\n");
				} p -= 1;
				if(bin[p] - 1 >= l) printf("0\n");
				else printf("1\n");
			} else {
				if(bin[o + 1] - 1 >= l) printf("0\n");
				else printf("1\n");
			}
		}
	}
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值