链接
题意
在[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
", x ^ y);
}
}