C. Maximum Set(区间范围)

Problem - C - Codeforces

 一个正整数集合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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值