题目链接
题意:给出四个数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; } }