首页 > 其他分享 >CF1796C Maximum Set

CF1796C Maximum Set

时间:2024-01-31 22:12:47浏览次数:25  
标签:le frac CF1796C int 选出 Maximum times Set 端点

原题传送门

当天比赛打完之后看了看跟我排名差不多的人的这题代码,感觉莫名其妙,写了几十行。我看了看我只有十几行的 AC 代码,陷入了沉思。

分析

题目的要求其实可以转换为:在区间 \([l_0, r]\) 中选择一些数,使得这些数排序后每个数都是前一个数的倍数,要求选的尽可能多。那既然要选的尽可能多,左端点肯定要选上,并且应该让每个数都是前一个数的两倍。这样才能使得选出的最多。设最多选出 \(k + 1\) 个数,那么有式子 \(l_0 \times 2^k \le r\) 成立,即选出的最大数小于等于区间右端点。于是得出 $k \le \log_2(\frac{r}{l_0}) $。于是 \(k\) 的最大值就是 $ \lfloor \log_2(\frac{r}{l_0}) \rfloor$。令 \(k\) 取最大值,则输出的第一个答案就是 \(k + 1\)。

接下来题目让我们求这样的集合个数。显而易见的一个暴力就是从左端点开始枚举,一直枚举到不存在符合要求的集合。这样可能会炸,所以考虑优化。

考虑二分答案。

怎么可能二分答案(虽然也不是不行)!显然我们可以把刚才那个式子拿过来用:\(l \times 2^k \le r\)。移项得 \(l_1 \le \frac{r}{2^k}\)。令 \(l_1\) 取最大值 \(\lfloor \frac{r}{2^k} \rfloor\),则在每个数都是前一个数的两倍的情况下,左端点 \(l \in [l_0, l_1]\)。所以答案应该是 \(l_1 - l_0 + 1\),因为从这个范围内的左端点开始往右都可以构造一个满足要求的集合。

你真以为就这么简单?

不可能的。

显然,在使选出的数最多的情况下,后一个数并不一定非要是前一个数的两倍。也可以是,比如说三倍,四倍什么的。在抱怨这题之前,让我们先仔细看看:后面一个数可以是前一个数的四倍吗?

显然不行。

若后面一个数是前一个数的四倍,那完全可以在中间再插一个数进去,使选出的数变多。顺着这个思路往下想,后面的数是前面数的五倍,六倍,甚至七倍,八倍,那显然也不行。所以在使得选出的数最多的情况下,后面的数最多是前面数的三倍。

猜你在想:排列组合。

你先别急。让我们接着想:若在选出的集合中有三个连续的数,分别叫 \(x_1, 3x_1, 9x_1\)。这个时候,我们发现,这三个数可以被四个数代替:\(x_1, 2x_1, 4x_1, 8x_1\)。这样,选出的数就又变多了。

发现什么问题?刚才的讨论说明了后面的数最多是前面数的三倍,而且最多只能有一个数是其前面数的三倍。于是我们可以再算出
一个临界点 \(l_2\),使得从 \([l_0, l_2]\) 中任意一个左端点开始都可以构造 \(k\) 个符合要求的集合(除此集合的左端点外,共有 \(k\) 个数可以是其前面数的三倍),而从 \((l_2, l_1]\) 中任意一个左端点开始都只能构造一个符合要求的集合。那接下来的任务就是算出 \(l_2\)。

什么?你不会还想二分答案吧!别啊,我们有更加迅速的做法:先前那个式子 \(l \times 2^k \le r\) 在这边改一改还能用:\(l_2 \times 3 \times 2^{k-1} \le r\),也就是把其中一个 2 换成 3。移项得 \(l_2 \le \frac{r}{3 \times 2^{k - 1}}\)。令 \(l_2\) 取最大值 \(\lfloor \frac{r}{3 \times 2 {k - 1}} \rfloor\),则答案为 \((l_2 - l_0 + 1) \times k + (l_1 - l_0 + 1)\)。

你真以为就这么简单?

是的,真就这么简单。写的时候注意一下精度问题就好了。

这里最终的 \(l_2\) 算出来可能会小于 \(l_0\),需要注意。

代码

#include <iostream>
#include <math.h>
#define int long long
using namespace std;
const int p = 998244353;
signed main() {
    int tc;
    cin >> tc;
    while (tc--) {
        int a, b;
        cin >> a >> b;
        int x = log2((1.0 * b) / a);
        int l = a, m = (b / 3) / (1 << x - 1), r = b / (1 << x); // l 是 l0, r 是 l1,m 是 l2,x 是 k。
        cout << x + 1 << " " << (r - l + 1 + (((m - l + 1) % p) * (x % p) * (m >= l)) % p) % p << "\n";
    }
    return 0;
}

完结撒花~~~

标签:le,frac,CF1796C,int,选出,Maximum,times,Set,端点
From: https://www.cnblogs.com/forgotmyhandle/p/18000230

相关文章

  • ABC306F Merge Sets
    原题链接分析观察要求的式子:\(\sum_{1\leqi\ltj\leqN}f(S_i,S_j)\),发现可以拆成每一个集合\(S_i\)的贡献的和。那么我们考虑每一个集合\(S_i\)的贡献。显然,对于每一个\(S_i\),其贡献就是\(\sum_{i\ltj\leqN}f(S_i,S_j)\),也就是它与其后每一个集合\(S_j\)的......
  • vue3-setup中如何通过ref调用子组件的函数
    vue3-setup中如何通过ref调用子组件的函数子组件通过defineExpose向外导出需要调用的函数在父子间中定义ref引用来调用子组件关键代码:<scriptsetup>import{ref,reactive,defineExpose}from'vue'constshow=ref(false);consttitle=ref('添加收款方式');con......
  • Debug: ERROR: Directory '*py3-none-any.whl' is not installable. Neither 'setup.
    [ERROR:Directory'*py3-none-any.whl'isnotinstallable.Neither'setup.py'nor'pyproject.toml'found.]kubectllgostrainer-pod-name-nkubeflow-->,pipeline_info=id:"detect_anomolies_on_wafer_tfdv_schema"......
  • android setprop getprop, 调整app heap 堆 大小
    网上的截图: 通过setprop设置的更改的属性,重启之后就会消失。 调整app堆大小。      一些基本的了解。  ......
  • QSplitter 分割 组件之setStretchFactor方法
    原型:voidQSplitter::setStretchFactor(intindex,intstretch)翻译:将索引位置的部件的大小策略更新为具有拉伸因子stretch。stretch不是实际的拉伸因子;实际的拉伸因子是通过将部件的初始大小乘以stretch来计算的。根据实际情况可知,如果俩个控件默认大小一样,若下标0的拉伸因......
  • modset.c
    / DRM双缓冲垂直同步模式设置方法 这个例子扩展了modeset-double-buffered.c,并引入了与垂直空格(vsync'ed)同步的页面翻转。垂直空白是显示控制器从扫描帧缓冲区中暂停的时间。垂直空白结束后,将逐行再次扫描framebuffer,并在后面跟着垂直空白。 在更改framebuffer时,垂直空格是......
  • 达梦---自定义函数 find_in_set()
    createorreplaceFUNCTIONFIND_IN_SET(piv_str1varchar2,piv_str2varchar2,p_sepvarchar2:=',')RETURNNUMBERISl_idxnumber:=0;--用于计算piv_str2中分隔符的位置strvarchar2(500);--根据分隔符截取的子字符串piv_......
  • DataSet 的 DisableControls 与 DataSet的EnableControls 作用(转)
    DataSet的DisableControls与DataSet的EnableControls作用(转)ClientDataSet与DataSet的DisableControls、EnableControls用法类似。对大量的数据做循环处理时,为了避免DataSet在游标不停地跑时,数据敏感控件随之不停刷新界面,导致代码运行速度下降,通常的做法是断开数据敏......
  • A Balanced Problemset?
    引言题目链接:https://codeforces.com/contest/1925/problem/B思路由于最后的答案是x分解的全部数的gcd,所以该答案一定是x的因数,只要遍历x的因数k,那么该因数能将x分解成\(\frac{x}{k}\)份。若\(\frac{x}{k}\geqn\),则可将其构造成n组,gcd为k的答案,只需要找到......
  • Unity5.x shader打包AssetBundle总结
    unity5.x  shader打包AssetBundle总结最近比较忙,好久没有更新博客了,新项目切换到unity5.x后使用了新的打包机制,在打包shader的时候遇到了一些问题,这里来记录一下吧。 在上一个项目中,我们使用unity4.7,对于shader并没有进行依赖打包,而是由unity打包到了每个用到的AssetBundle......