题意:给出四个数a,b,c,d。选择a<=x<=b,c<=y<=d,求x XOR y的最大值。
考虑从高位到低位贪心,对于每一位,如果x,y只有唯一的取法,那么只能这么取;否则贪心地必须使答案的这一位等于1。如果x,y都是0,1都能取,则设这是从右向左数第len位,因为x,y能取的值一定都是连续的一段,因此x,y的后len位都能取0111...1(len-1个1)和1000...0(len-1个0)(否则做不到从右向左数第len位都能取0,1)。也就是说,后len位的贡献一定能达到可能的上界111...1(len个1)。此时不必继续考虑后面的位。
如果x,y在这一位并不是0,1都能取,那么由于要使得答案的这一位等于1,也只有唯一的取法。
至此,这一位考虑完毕,然后根据选取的方案,修正一下x和y的范围,然后对后一位做即可。
#include <iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define LL long long
using namespace std;
int main()
{
int T;
cin>>T;
while(T--)
{
LL a,b,c,d,ans=0;
cin>>a>>b>>c>>d;
for(int i=62;i>=0;i--)
{
LL t=(LL)1<<i;
int x0=0,x1=0,y0=0,y1=0;
if(b>=t) x1=1;
if(d>=t) y1=1;
if(t-1>=a) x0=1;
if(t-1>=c) y0=1;
if(x1&&y1&&x0&&y0)
{
ans+=2*t-1;
break;
}
if(x1&&y0)
{
ans+=t;
a-=t;
b-=t;
continue;
}
if(x0&&y1)
{
ans+=t;
c-=t;
d-=t;
continue;
}
if(x0==0&&y0==0)
{
a-=t;
b-=t;
c-=t;
d-=t;
}
}
cout<<ans<<endl;
}
}