传送门:cf 484A
给定一个范围[l,r],求出范围内二进制下1位数最多且最小的数
需要保证数最小,因此从左端点开始,从最低位开始不断找其中二进制下的0位,把0变成1之后(整体数会增大),判断数是否还在范围内,若已经超过r则当前数即为结果,否则继续该操作
/******************************************************
* File Name: a.cpp
* Author: kojimai
* Create Time: 2014年11月06日 星期四 00时33分06秒
******************************************************/
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
long long a[64];
void init()
{
a[0] = 0;
long long tmp = 1;
for(int i = 1;i <= 63;i++)
{
tmp = tmp * 2;
a[i] = tmp - 1;
}
}
int getnum(long long x)
{
int ret = 0;
while(x)
{
if(x%2 == 1)
ret++;
x/=2;
}
return ret;
}
long long getze(long long x)
{
long long ret = 1;
while(x%2==1)
{
ret *= 2;
x /= 2;
}
return ret;
}
int main()
{
int n;
init();
cin>>n;
while(n--)
{
long long x,y;
cin>>x>>y;
int num = getnum(x);
if(a[num] >= x)
{
while(a[num+1] <= y && num < 64)
{
num++;
}
cout<<a[num]<<endl;
}
else
{
long long tt = x;
long long t1 = getze(tt);
while(tt + t1 <= y)
{
tt = tt + t1;
t1 = getze(tt);
}
cout<<tt<<endl;
}
}
return 0;
}