题意:中文
思路:首先要想尽可能得出最大位或,最高位应该尽量选1然后在此前提下,其它的位应该尽量选1,因此,r必须是选的。然后就从最低位开始往上遍历r,遇到0则找到能把当前这一位变成1的最大值(这个数一定是小于r的),并判断是否大于等于l。如果在范围内的话,就将这一位变成1.
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=100;///注意这里的数组的大小
int T,cnt;
long long l,r,k,sum;
long long bi[maxn];
long long pow(long long x){///求pow(2,x)不能直接1<<x大概是数据的原因
if(x==0) return 1;
long long s=1;
while(x--){
s<<=1;
}
return s;
}
int main(){
while(scanf("%d",&T)!=EOF){
for(int cas=1;cas<=T;cas++){
cnt=0;
memset(bi,0,sizeof(bi));
scanf("%lld%lld",&l,&r);
long long rr=r;
while(rr) bi[cnt++]=(rr&1),rr>>=1;///r转化成二进制从右到左存入bi数组
sum=0;
for(int i=0;i<cnt;i++){
if(bi[i]==0){
k=r-sum-1;///求出使第i位0变成1的最大值
if(k>=l) bi[i]=1;
}
else
sum+=pow(i);
}
long long ans_final=0;
for(int i=0;i<cnt;i++)
ans_final+=pow(i)*bi[i];
//printf("%lld\n",ans_final*1ll);
cout<<ans_final<<endl;
}
}
return 0;
}