这个集合里的数后一个一定是后一个数为前一个数的倍数,那么2倍肯定是最好的,刚刚读题发现可以相等,那么不就是无限大了?, 最小数是l, 先算出 l 连乘几个2会刚好小于等于r , 假设为num,那么第一个需要输出的数就是num,再通过二分找有多少个数能连乘num个2 <= r,但这还比实际答案小,因为还有一种情况是乘3,(4及以上不行因为4已经是2的倍数),多一个3多1.5倍,多两个是2.25倍就相当于多放一个2多一点,但是原num已经是最大的2,再放就超过r了,所以3最多只能放一个,也可以用二分来求
#include<iostream>
#include<cmath>
using namespace std;
int num;
int l, r;
bool check1(int mid)
{
if(mid * pow(2, num - 1) <= r)
return true;
return false;
}
bool check2(int mid)
{
if(mid * pow(2, num - 2) * 3 <= r)
return true;
return false;
}
int main()
{
int t;
cin >> t;
while(t --)
{
int ans = 0;
scanf("%d%d",&l, &r);
int dif = r / l;
num = log2(dif) + 1;
int ll = l - 1, rr = r + 1;
while(ll < rr)
{
int mid = (ll + rr + 1) / 2;
if(check1(mid))
{
ll = mid;
}
else
rr = mid - 1;
}
if(ll != l - 1)
ans += ll - l + 1;
ll = l - 1, rr = r + 1;
while(ll < rr)
{
int mid = (ll + rr + 1) / 2;
if(check2(mid))
{
ll = mid;
}
else
rr = mid - 1;
}
if(ll != l - 1)
ans += (ll - l + 1) * (num - 1 );
cout << num << " " << ans << endl;
}
}