#include<iostream>#include<cstdio>#include<string>#include<string.h>#include<cstring>#include<algorithm>using namespace std;int cal(long long d){
int len = 0;
while(d){
d >>= 1;
++len;
}
return len;}int main(){
int n;
scanf("%d", &n);
long long l, r;
for(int i = 0; i < n; ++i){
scanf("%I64d%I64d", &l, &r);
int rlen = cal(r), llen = cal(l);
if(rlen > llen){ //length of r is longer than length of l
if(rlen == (1LL << rlen) - 1){
printf("%I64d\n", r);
}
else{ //number with maximum 1 below r
printf("%I64d\n", (1LL << (rlen - 1)) - 1);
}
}
else{
for(int i = 0; i < rlen; ++i){ //from low bit to high bit, test if l can be higher
if((l | (1LL << i)) > l && ((l | (1LL << i)) <= r)){
l |= 1LL << i;
}
}
printf("%I64d\n",l);
}
}
return 0;}
这道题用了构造的方法,之所以没想到也是因为对位运算不熟悉,看到题目除了枚举没有想到别的好办法,
思路已经在注释里写出来了
总结一下学到的技巧:
用逐位右移的方法求一个non-negative integer的位数
if length of a non-negative integer d is len, then 1 << len is larger than d with 1 in the left most
using operator | rather than + can update a specified integer faster