题目描述
B君和G君聊天的时候想到了如下的问题。 给定自然数l和r ,选取2个整数x,y满足l ⇐ x ⇐ y ⇐ r ,使得x|y最大。 其中|表示按位或,即C、 C++、 Java中的|运算。
Input
包含至多10001组测试数据。 第一行有一个正整数,表示数据的组数。 接下来每一行表示一组数据,包含两个整数l,r。 保证 0 ⇐ l ⇐ r ⇐ 10181018。
Output
对于每组数据输出一行,表示最大的位或。
样例
Sample Input
5
1 10
0 1
1023 1024
233 322
1000000000000000000 1000000000000000000
Sample Output
15
1
2047
511
1000000000000000000
分析
很简单的一个贪心,要想异或和最大,显然尽可能让每一位上的数字都为1,我们就从较小的数开始枚举,从最低位开始,将不为1的数位逐个变为1,当aa大于等于bb时跳出循环,输出aa|bb就可以了,十多行代码就可以解决问题
要注意两个坑:
1、位运算默认的是int,要强制类型转换乘long long,否则会aa的值会变为-1,死循环,就会T掉
2、最后要输出aa|bb,不能输出aa,比如0 1这组数据
代码
#include<cstdio>
using namespace std;
typedef long long ll;
int main(){
ll aa,bb,t;
scanf("%lld",&t);
while(t--){
scanf("%lld%lld",&aa,&bb);
ll now=0;
while((aa|((long long)1<<now))<bb) aa|=((long long)1<<now),now++;
printf("%lld
",aa|bb);
}
return 0;
}