首页 > 其他分享 >CF710D Two Arithmetic Progressions 题解

CF710D Two Arithmetic Progressions 题解

时间:2024-03-23 20:24:09浏览次数:28  
标签:CF710D 题解 a1 b1 text Progressions lcm 根号 暴力

CF710D Two Arithmetic Progressions

根号分治薄纱数论

看日报学习的根号分治:暴力美学——浅谈根号分治 - paulzrm 的博客

开始想学ODT的映射思想的推广 - 金珂拉 的博客,结果先学了 ODT,又学了根号分治,才搞懂前置知识。

  1. 什么是根号分治

    根号分治,是暴力美学的集大成体现。与其说是一种算法,我们不如称它为一个常用的 trick。

    其实就是将两个极端的暴力算法融合,根据不同数据选择更优的暴力,即可保证复杂度始终在可接受范围内。

  2. 如何使用根号分治

    即写出两个不同暴力算法(通常是在小范围内很快的和在大范围内很快的),之后确定一个阈值,在不同范围选择不同暴力。

大概根号分治就是这样,具体请看暴力美学——浅谈根号分治 - paulzrm 的博客

在这道题中,我们需要思考两种方法(定 $t$ 为阈值,默认 $a_1\ge a_2$,默认 $l=\max(l,\max(b_1,b_2))$):

  1. $a_1\le t$,则 $a_2\le t$。以 $\text{lcm}(a_1,a_2)$ 为一个循环节,显然的,一个循环节内至多有一个数同时出现在两个数列中。因此暴力枚举 $[\ l,\min(l+\text{lcm},r)\ ]$ 中的每一个数,若有 $i$ 使得 $i\in \text{数列1}\ \text{and}\ i \in \text{数列2}$,则可知共有 $\frac{(r-i)}{\text{lcm}+1}$ 个满足条件的值;反之没有所求值,输出 0

  2. $a_1\gt t$。则可以暴力枚举 $\text{数列1}$ 中的每一个处于 $[\ l,r\ ]$ 的数,若它同时处于 $\text{数列2}$ 则 ans++

之后,我们进行复杂度分析:

  1. 对于暴力1:时间复杂度为 $O(\text{lcm}(a_1,a_2))$。
  2. 对于暴力2:时间复杂度为 $O(\frac{r-l+1}{a_1})$。

以下内容不保证正确性(数学太差了):

故期望复杂度 $O(\text{lcm}(a_1,a_2)+(\frac{r-l+1}{a_1}))$,即 $O((t\times a_2)+(\frac{2e9}{t}))$,对于 $a_2$ 有限制 $a_2\le t$,使 $a_2=t$,则可算出阈值 $t=\sqrt[3]{2e9}$。约 $1259$。

对于阈值的计算并不准确,如果有更优方法欢迎指正。

代码:

//pre
const int t=1259;
signed main() {
	LL ans=0;
	LL a1,b1,a2,b2,l,r;
	read(a1,b1,a2,b2,l,r);
	if(b1>l) l=b1;
	if(b2>l) l=b2;	//保证l的大小为 b_1,b_2,l 中的最大值
	if(a2>a1) swap(a1,a2),swap(b1,b2); //保证 a_1>a_2
	LL lcm=a2*a1/__gcd(a1,a2);	//计算lcm  (lcm(a,b)*gcd(a,b)=a*b)
	if(a1<t) { 	//a_1 小于阈值
		for(int i=l;i<=min(l+lcm,r);i++) {
			if((i-b1)%a1==(i-b2)%a2&&(i-b2)%a2==0) {	//若满足题意
				ans=(r-i)/lcm+1;	//剩下有几个循环节并加上当前位置的一个
				break;
			}
		}
	}
	else {
		LL x;
		if(b1>=l) x=b1;
		else x=b1+ceil(1.00*(l-b1)/a1)*a1;//确定从哪里开始枚举(起始点要属于数列1)
		for(;x<=r;x+=a1) if((x-b2)%a2==0&&(x-b2)/a2>=0) ++ans;	//满足题意则ans++
	}
	write(ans); //输出
	return 0;	//好习惯捏
}

pre 前的内容为头文件与快读快写,如果需要戳这里

标签:CF710D,题解,a1,b1,text,Progressions,lcm,根号,暴力
From: https://www.cnblogs.com/cheemsadoge/p/18091612

相关文章

  • [暴力题解系列]2023年蓝桥杯-子串简写
    ​ 大伙都说暴力是最低级的算法,啊那确实。但是好的暴力才是真正牛逼的骗分。咱就是说,暴力如何骗分呢?就是基于最暴力的算法一步步优化到能得更多分的暴力。子串简写这题,首先第一步就能想到一件事情:暴力枚举子串开头和末尾的位置,检查是否是符合题目要求的字符,如果是,并且长度大于......
  • 题解:AT_arc174_a [ARC174A] A Multiply
    题传。先要将\(C\)分类。\(C>0\),为了使答案更大,要乘上一个最大的区间和。\(C\le0\),为了使答案更大,选择乘上一个最小的区间和,因为此时我们可以贪心地想,如果区间和越小,乘上一个负数或\(0\)后,答案减少得越小,甚至乘上负数,还会使答案增大,所以也可以用负负得正来解释。当......
  • P8756 [蓝桥杯 2021 省 AB2] 国际象棋 题解
    设计状态什么的就不讲了,这里是对其它题解的优化。怎么优化呢,我们可以知道的是我们只要明确了当前行的状态,上一行的可选集就是知道的,如果我们明确了当前行以及上一行的状态,那么上上行的可选集就是知道的,于是我们就可以使用二进制子集枚举来写,这样就减去了全部不合法的枝叶,我们可以......
  • CF794F Leha and security system 题解
    题目链接:CF或者洛谷首先观察到题目的修改\(x\rightarrowy\),是每个位置的\(x\)都要变,那就显然的拆位去算每一位的贡献。当然,你又发现\(x\rightarrowy\),这玩意属于值为\(x\)的位变化成\(y\),那么这个和普通的拆位区别就在于这是维护值域维的拆位,我们拆位\(0\sim9\)......
  • [HDU5396] Expression 题解
    每次合并两个数,做过石子合并的人都能看出来是区间dp。设状态\(dp_{i,j}\)表示区间\([i,j]\)中合并为一个数的所有情况之和。那么我们就可以枚举断点\(k\):\(b_k\)为\(+\):\([i,k]\)中的每种情况都要和\([k+1,j]\)中的每种情况产生一个贡献,所以总贡献为\(dp_{i,k}\ti......
  • 2024年3月22号题解
    Fliptile解题思路对于这个题目可以用递推来写因为每次翻转只会影响一个十字架的区域,所以如果我们知道第一行的情况,那么是不是只要把第一行的所有的1在对应的下一个行的相同位置进行翻转就可以把第一行的所有的1变成0呢(重要性质) 那么只要我们不断递推下去就可以得到最后一......
  • CF1946E 题解
    Blog赛场上差一点做出来。首先发现左右两部分是比较独立的,所以可以分开计算后合并。注意到我们可以把整个数集分成左右两部分,即\(\binom{n-1}{p_{m1}-1}\)。然后我们不妨只考虑左边。发现左边的最大值也已经确定,且最大值右边的所有数可以随便选,即\(\binom{p_{i+1}-......
  • CF1948G MST with Matching 题解
    洛谷题面CF题面题目要求一个最小值加上一个最大值的最小值,不好直接做,考虑转化。发现树是二分图,而由柯尼希定理可知二分图的最大匹配等于其最小点覆盖。这样就把求\(\min(\min_{\text{生成树}}+\max_{匹配})\)转化为了\(\min(\min_{生成树}+\min_{覆盖})\)。直接\(\math......
  • CF1618G Trader Problem 题解
    题目链接:CF或者洛谷本题挺有意思的,我们观察到\(\lek\)这个限制使得我们可以将原序列进行分组,把\(\lek\)的限制的元素放在一组中,那么根据题意,这组当中任意元素之间都是可以互相交换的,包括系统用品。那么假设一组中有\(x\)个自身的物品,\(y\)个系统物品,那么这\(x+y\)物......
  • uni-app/小程序自定义导航栏下拉刷新loading图标看不到问题解决
    实际效果图 我们在page.json中开启了自定义导航栏属性和下拉刷新属性后//开启下拉刷新"enablePullDownRefresh":true//自定义导航栏"navigationStyle":"custom"此时,页面中的下拉刷新三个小圆点会被我们的导航栏遮盖住,导致用户下拉刷新看不到loading效果,如下图:......