这题写起来很奇怪所以发个博客以后复习,
题意 是给你两个区间, 让你从中选出两个数,使得他们的异或值最大,1e18的范围,
取得异或值最大肯定要高位越大越好了,一路贪下去
那么分情况讨论,计算在第x位的时候两个数可以取0还是1还是都可以,所以写一个判断函数,(由于都可以不好讨论不妨求出只能是0和只能是1的)
当两个数都是都可以取时候要注意,
这里贪心 将能剩余选择空间更大的取1,显然用上界减去现在的就是剩余空间,(这里我也当时是猜的,一交居然ac了,
放代码,代码巨搓,本蒟蒻还在努力中。。。
#include <iostream>
#include <cstdio>
using namespace std;
long long a,b,c,d;
const long long on=1;
long long x1=0,x2=0;
long long c1,c2;
inline long long pan(long long x,long long a,long long b,int cnt){
if((x|(on<<cnt))>b)
return 0;
if((x|(on<<cnt))<a)
return 1;
return 2;
}
int main()
{
int t;
cin>>t;
while(t--){
scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
x1=0,x2=0;
for(int i=60;i>=0;i--){
c1=pan(x1,a,b,i);
c2=pan(x2,c,d,i);
if(c1==2&&c2==2){
if(b-(x1|on<<i)>d-(x2|on<<i)){
x1=(x1|(on<<i));
}
else{
x2=(x2|(on<<i));
}
}
else if(c1!=2&&c2==2){
x1=(x1|(c1<<i));
if(c1==0)
c2=1;
else
c2=0;
x2=(x2|(c2<<i));
}
else if(c1==2&&c2!=2){
x2=(x2|(c2<<i));
if(c2==0)
c1=1;
else
c1=0;
x1=(x1|(c1<<i));
}
else{
x1=(x1|(c1<<i));
x2=(x2|(c2<<i));
}
}
printf("%lld
",x1^x2);
}
return 0;
}