HDU 5661 Claris and XOR 贪心

链接

HDU 5661 Claris and XOR

题意

在[a,b]与[c,d]的范围内找两个数x,y是的异或值最大

思路

从高位到到低位贪心,判断当前是否能加1或0,如果x和y均能为1或0的话,后面的就全都可以确定不用考虑了,当时就是没想到这一点

代码

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#define LL long long
#define INF 0x3f3f3f3f
#define eps 1e-8

using namespace std;

bool vis1[3], vis2[3];
LL a[6];
bool check(LL x, int p, LL L, LL R){
	LL y = x + (1LL << p) - 1;
	if (x <= R && y >= L) return true;
	return false;
}
int main(){
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
	int T;
	scanf("%d", &T);
	while (T--){
		LL mx = -1;
		for (int i = 1; i <= 4; ++i){
			scanf("%I64d", &a[i]);
			mx = max(mx, a[i]);
		}
		int p = 0;
		while ((1LL << p) <= mx){
			++p;
		}
		LL x = 0, y = 0;
		for (int i = p - 1; i >= 0; --i){
			memset(vis1, 0, sizeof(vis1));
			memset(vis2, 0, sizeof(vis2));
			if (check(x + (1LL << i), i, a[1], a[2])){
				vis1[1] = true;
			}
			if (check(x, i, a[1], a[2])){
				vis1[0] = true;
			}
			if (check(y + (1LL << i), i, a[3], a[4])){
				vis2[1] = true;
			}
			if (check(y, i, a[3], a[4])){
				vis2[0] = true;
			}
			if (vis1[0] && vis1[1] && vis2[0] && vis2[1]){
				x += (1LL << i) - 1;
				y += 1LL << i;
				break;
			}
			if (!vis1[0] && vis2[0]){
				x += 1LL << i;
				continue;
			}
			if (!vis1[1] && vis2[1]){
				y += 1LL << i;
				continue;
			}
			if (!vis2[0] && vis1[0]){
				y += 1LL << i;
				continue;
			}
			if (!vis2[1] && vis1[1]){
				x += 1LL << i;
				continue;
			}
			if (vis1[1] && vis2[1]){
				x += 1LL << i;
				y += 1LL << i;
			}
		}
		printf("%I64d\n", x ^ y);
	}
}

posted on 2016-04-10 12:14  张济  阅读(169)  评论(0编辑  收藏  举报

导航