Let's denote as the number of bits set ('1' bits) in the binary representation of the non-negative integer x.
You are given multiple queries consisting of pairs of integers l and r. For each query, find the x, such that l ≤ x ≤ r, and is maximum possible. If there are multiple such numbers find the smallest of them.
The first line contains integer n — the number of queries (1 ≤ n ≤ 10000).
Each of the following n lines contain two integers li, ri — the arguments for the corresponding query (0 ≤ li ≤ ri ≤ 1018).
For each query print the answer in a separate line.
3 1 2 2 4 1 10
1 3 7
The binary representations of numbers from 1 to 10 are listed below:
110 = 12
210 = 102
310 = 112
410 = 1002
510 = 1012
610 = 1102
710 = 1112
810 = 10002
910 = 10012
1010 = 10102
题意:给一个l和r的区间,找出其中二进制中1的个数最多的数,如果有多解输出最小的数。
思路:首先l和r二进制化后从最高位往下看,如果存在不一样的时候,就让这位为0,低位全部为1,有一特殊情况就是r的这位后面全是1,这个时候就全变成1即可。
AC代码如下:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
ll num1[100],num2[100],num3[100];
int main()
{
int T,t,n,m,i,j,k,len1,len2;
ll l,r,ans,ret;
bool flag;
scanf("%d",&T);
while(T--)
{
memset(num1,0,sizeof(num1));
memset(num2,0,sizeof(num2));
scanf("%I64d%I64d",&l,&r);
len1=0;
while(l)
{
num1[++len1]=l%2;
l/=2;
}
len2=0;
while(r)
{
num2[++len2]=r%2;
r/=2;
}
for(i=len2;i>=1;i--)
{
if(num1[i]==num2[i])
num3[i]=num2[i];
else
{
num3[i]=0;
break;
}
}
flag=true;
for(k=i;k>0;k--)
if(num2[k]==0)
flag=false;
for(k=i;k>0;k--)
num3[k]=1;
if(!flag)
num3[i]=0;
ans=0;
for(i=len2;i>=1;i--)
ans=ans*2+num3[i];
printf("%I64d\n",ans);
}
}