题目链接https://ac.nowcoder.com/acm/contest/543/C

题意:闭区间L,R中,任选两数异或,求最大值。

解 首先,L,R,可以被看成两个01序列,且R>=L。思考这样一个事情:如果(int)L,R/2不相等,那么最大值就确定了,因为在这种情况下将他们大小比较一下,最高位R一定是1,L一定是0,所以R一定>=100...(n个0),L一定<=011...(n个1),所以在这种情况下,最大值便是这两个数异或,得11(n+1个1)。那么,如果L,R的最高位一样呢,那么L,R中异或的最大值的最高位一定是0了,所以这个问题就变成了去掉最高位后,按上述规则找最大值。当然,要考虑到,如若L=R,最大值为0,这种情况也是满足上述说明的。

代码:

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
ll l,r;
int cnt1,cnt2;
int a[100],b[100];
int t;
bool flag=false;
ll solve(int x){
 long long ans=1;
 for(int i=1;i<=x;i++)ans*=2;
 return ans;
}
int main(){
 scanf("%d",&t);
 while(t--){
  memset(a,0,sizeof(a));memset(b,0,sizeof(b));
  scanf("%lld%lld",&l,&r);
  while(l){
   a[++cnt1]=(l%2);
   l/=2;
  }
  while(r){
   b[++cnt2]=(r%2);
   r/=2;
  }
  if(cnt2>cnt1){
   int t=cnt2-cnt1;
   for(register int i=1;i<=t;i++)a[++cnt1]=0;
  }
  for(register int i=cnt2;i>=1;i--){
   if(a[i]==0&&b[i]==1){printf("%lld\n",solve(i)-1);flag=true;break;}
  }
  if(flag==false)printf("0\n");
  flag=false;
  cnt1=0,cnt2=0;
 // for(register int i=cnt2;i>=1;i--)printf("%d",a[i]);
 // printf("\n");
 // for(register int i=cnt2;i>=1;i--)printf("%d",b[i]);
 }
}