题意:给定自然数l和r ,选取2个整数x,y满足l <= x <= y <= r ,使得x|y最大。
分析:很容易想到l,r用二进制表示一定是由一段相同的前缀与剩下不同的部分组成,
比如l=X0A,r=X1B,其中这里X,A,B是一段二进制数,这里A,B的位数显然要相同(可以有前导0,如A=000011,B=011111,X=0等)
很容易想到此时的最大值就是X1...1,这里连续1的总个数是A,B的位数+1
而此时题目中的x=X01...1,这里连续1的总个数是A,B的位数
y=X10...0,这里连续0的总个数也是A,B的位数
那么如何证明这个数是最大值呢?
显然x,y一定有X这个部分,而剩余部分能产生的最大值显然是都为1的情况
那么如何证明这个数(x,y取值)是符合要求的呢?(l≤x≤y≤r)
显然x≤y,l≤x,y≤r(跟没说一样,但真的很显然)
所以我们只需要找到l和r不一样的一位,然后把这里及其后面都变成1即可
这里有个要注意的小细节就是1<<i的类型只与1有关,如果你写1<<i的话,这个值就是int类型
如果你写1ll<<i的话,这个值才是ll类型
代码:
#include<cstdio> using namespace std; #define ll long long int main() { int t; ll l,r; scanf("%d",&t); while(t--) { scanf("%lld%lld",&l,&r); if(l==r) { printf("%lld ",l); continue; } for(ll i=62;i>=0;i--) { if((l&(1ll<<i))!=(r&(1ll<<i))) { printf("%lld ",r|((1ll<<i)-1ll)); break; } } } return 0; }