C. Maximum Set[数学] [*1300-*1500]
C. Maximum Set[数学] [*1300-*1500]
题意:
一个集合是漂亮的,如果他的每一个元素都是集合中其他元素的倍数或者因子
给定你一个 \(l\) 和 \(r\)
让你找出在 \((l,r)\) 区间内可以组成的元素数量最多的漂亮的集合
并给出元素数量最多的集合的数目
思路:
如果每一个元素都是其他元素的倍数或者因子
我们定义 $${ v = \lim\limits _{n \to 0} \frac{\Delta ans}{\Delta n} }$$ (\(v\) 是贡献率,为瞬时 \(n\) 变化时对答案 \(ans\) 的贡献率)
那么我们可以发现,当倍数都是2时,对答案的贡献率 \(v\) 是最大的
也就是到相同的长度需要的元素大小最小(可以观察发现,不再进行证明)
但是
还有一种特殊情况
也就是比如说 在 \((4,100)\) 区间内
从 \(4\)~\(64\) 的长度是5
如果将其中的一个2倍替换成3倍呢
那么 \(4\)~\(96\) 的长度也是5
我们发现也是可以成立的
如果将两个2倍替换成3倍呢
我们可以发现\(3*3>2*2*2\)
所以如果存在这种情况我们就可以将 两个3替换成三个2
从而让集合的长度加一
那么我们将其中的一个2倍替换成4倍呢
这种情况就不行了
为什么呢?
因为4倍可以拆成两个2倍,也就是在元素大小相同的情况下,2倍可以让集合的长度更长
所以也就是不存在的
大于4的情况因为 \(v\) 均比4的情况小
所以也都是不存在的
那么我们就将情况化简成立了仅有全是2 和 仅有一个3的情况
那么就可以愉快的解决这道问题了
key code
int l,r;
void solve(){
//try it again.
cin>>l>>r;
int k=0;
while((1<<k)*l<=r)k++;k--;
int ans=(r>>k)-l+1;
if(k>0){
r>>=k-1;
r/=3;
if(r>=l)ans+=k*(r-l+1);
}
cout<<++k<<" "<<ans<<endl;
}

浙公网安备 33010602011771号