一个正整数集合S被称为漂亮的,如果这个集合中的每两个整数z和y,要么z除y,要么y除æ(或两者皆有)。给定两个整数I和r。考虑所有由不小于I且不大于r的整数组成的漂亮集合。你必须打印两个数字:所有元素从l到r的美丽集合的最大可能大小;由从l到r的具有最大可能大小的整数组成的漂亮集合的数目。因为第二个数字可以很大,所以对998244353取模打印。输入第一行包含一个整数t (1 <t <2-104)——测试用例的数量。每个测试用例由一行组成,包含两个整数l和r (1 <l<r < 10f)。输出对于每个测试用例,打印两个整数——由从l到r的整数组成的漂亮集合的最大可能大小,以及具有最大可能大小的这样的集合的数量。因为第二个数字可以很大,所以对998244353取模打印。
input
Copy
4
3 11
13 37
1 22
4 100
output
Copy
2 4 2 6 5 1 5 7
请注意在第一个测试用例中,包含从3到11的整数的漂亮集合的最大可能大小为2。有4个这样的集合,它们具有最大的可能大小:{3, 6};{3, 9}; {4, 8};{5, 10}.
题解:
根据集合定义,不能有相同的数,要让给定集合最大,每次应该*2
按照第四个样例
4 100
4 8 16 32 64
最大为5
这是其中一个解,我们可以得到一个边界
其中部分答案很容易想到,r/2^(5-1) - (l - 1)
还有一部分,我们可以思考是否可以在*2中插入一个*3 代替*2
max(0ll,(r/(p/2*3)) - (l -1))有几个(l~r/(p/2*3))满足可以替换
*(cnt-1)代表后面几个空可以替换
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<vector>
#include<map>
#include<queue>
using namespace std;
#define int long long
const int N = 6e6 + 10;
#define ios ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
void solve()
{
int l,r;
cin >> l >> r;
int cnt = 1;
int p = 1;
if(l*2 > r)
{
cout <<1<<" "<<r - l + 1<<"\n";//要特判,否则后面会/0导致re
return ;
}
for(int i = 2*l;i <= r;i *= 2)
{
cnt++;
p = p*2;
}
cout << cnt <<" ";
int ans = r/p - (l-1) + max(0ll,(r/(p/2*3)) - (l -1))*(cnt - 1);//若p为1,除2后变成0了
cout << ans << "\n";
}
signed main()
{
// ios;
int t = 1;
cin >> t;
while(t--)
{
solve();
}
}
//3 F
//5 B
//6 F
//9 F
//10 B
//12 F
//15 FB
//18 FB