C. Maximum Set codeforces1796C

Problem - C - Codeforces

题目大意:给出两整数l,r,要求构造a数组,每个数都不同且在区间[l,r]之间,且任意两个数之间都有整除关系,问符合这些条件的数组的最大长度,以及该长度下满足条件的数组个数

1<=t<=2e4;1<=l<=r<=1e6

思路:既然要数字最多,那么我们按照贪心的思想,先选l作为第一个数,然后后面每一个数都是前一个数*2那么最大长度m就是log_{2}(r/l)+1这样的数组的l的取值范围就是从l到r/2^(m-1),那么这样的数组的数量就是r/2^(m-1)-l+1,然后我们发现在*两次2之间还有可能是*一次3,因为*3是小于*4的,所以我们对于之前求出的一个合法数组,可以把任意位置上的*2替换为*3都是合法的,那么这样的数组的l的取值范围就是从l到r/2^(m-1)*2/3,对于每一个l,都有(m-1)种合法的替换,因为*其他数都不比*两个2或*1个3更优,所以答案就是这两种情况下的答案相加

//#include<__msvc_all_public_headers.hpp>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MOD = 998244353;//实际上答案没有这么大,完全不用取模,还能这么增加难度?
int main()
{
	cin.tie(0);
	cout.tie(0);
	ios::sync_with_stdio(false);
	int t;
	cin >> t;
	while (t--)
	{
		ll l, r;
		cin >> l >> r;
		ll l2 = l;
		ll m = 1;//数组的初始长度为1
		while (l2*2 <= r)
		{//取log2
			l2 *= 2;
			m++;
		}
		ll ans = 0;
		ll temp2 = r / (1 << (m - 1));//都是*2时,最小元素的最大值
		if (temp2 >= l)
		{
			ans += temp2 - l + 1;
		}
		ll temp = r / (3 * (1 << (m - 2)));//有一个*3时,就*一个2在/3
		if (temp >= l)
		{
			ans += (temp - l + 1)*(m-1);//每一个数组都有m-1个位置可以放*3
		}
		cout << m << " " << ans << endl;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

timidcatt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值