Educational Codeforces Round 144 (Rated for Div. 2) C - Maximum Set

传送门

题意:

对于一个集合,如果它的任意两个元素都能 有 其中一个能整除另一个,那么它是好的。问在区间[L,R] 中由这个区间某些数内构成的好的集合的最长长度是多少,以及且满足这个长度的好集合有多少个。(懒得想就借鉴了j宝的题面,感兴趣的也可以看看)。

思路
让我们首先考虑怎么获得他的最长的长度,对于集合中任意相邻的两个数中,相差的倍数一定为质数(合数可以由质数的乘机得到),而且一定是最小的质数2,那么可以从l出发,不断的×2知道小于r为止,此时这个数为p,得到的长度即为最长的长度。

然后从最长的长度sum来分析,里面包含的数可以简要概括为
(l,2×l, 4×l,8×l,…)那么如果我们想在其中改变数字以获得更多的满足条件的序列的话,那么我们只需要从两部分分析:序列中只有二和序列中只有一个三的情况(如果有大于3或者两个以上的三的情况那么都可以转变为更多的2的情况那么就不符合条件)。

1.序列中全部为2的情况那么能改变的就只有l,l通过不断的累加然后去找到一个最大的L满足L+p/l<=r,那么L<=r-p/l,
然后满足条件的序列的数量就为sum2=L-l+1,这就是全为2的情况。
2.序列中有一个3的情况,那么就相当于p里面少了个因子2,多了个因子三,然后继续去寻找最大的L即可。具体看代码.

ps:如果l*2>r满足的话,那么就说明l连一个因子2也加入不进去,那么长度就为 1,数量就为区间和,输出即可。

代码

void slove( )
{
	int l,r;
	cin>>l>>r;
	int p=l;
	int sum=1;
	if(l*2>r){cout<<1<<" "<<r-l+1<<endl;return ;}

	while(p*2<=r){p*=2,sum++;}
	p/=l;

	ll sum2=max(0,r/p-l+1);p/=2;p*=3;
	ll sum3=max(0,r/p-l+1);

	cout<<sum<<" "<< sum2+sum3*(sum-1)<<endl;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值