求区间内最大的最大公约数

题目描述

鸡尾酒的数学很差,他学了很长时间的最大公约数,终于有一天他会求最大公约数了。 

于是他迫不及待地向你提问——给定数轴上的区间 [l, r],你可以从中任选两个不相同的整数,求它们的最大公约数。

请问它们的最大公约数最大为多少?

输入

输入两个正整数 l,r ,意义如题面所示。

输出

输出一行一个正整数表示答案。

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int l, r;
	cin >> l >> r;
	for (int i = r; i >= 1; i--)
	{
		int ll = ceil(1.0 * l / i) *i;
		int rr = floor(1.0 * r / i)*i ;
		if (ll<r&&ll!=rr)
		{
			cout << i;
			break;
		}
	}
}

同学的思路,拿来保存一下

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
我们可以使用线段树来解决这个问题。对于每个区间,我们都可以预处理出其内部所有数的最大公约数,然后在询问时,查询覆盖该询问区间的所有区间的最大公约数并取最大值即可。 具体地,我们可以将二维区间 $(i,j)$ 分别看作 $i$ 和 $j$ 两个维度,建立一颗二维线段树。对于每个节点 $(x,y)$,它表示的区间为 $[l_x,r_x]\times[l_y,r_y]$,其中 $l_x,r_x,l_y,r_y$ 分别表示该节点在 $x$ 和 $y$ 维度上的左右边界。我们可以在每个节点上维护一个值 $g_{x,y}$,表示区间 $[l_x,r_x]\times[l_y,r_y]$ 内部所有数的最大公约数。 对于每个节点 $(x,y)$,我们可以通过递归地计算其左右儿子节点的 $g$ 值来出该节点的 $g$ 值。具体地,我们可以将节点 $(x,y)$ 表示的区间分成四个子区间,分别为 $[l_x,\lfloor\frac{l_x+r_x}{2}\rfloor]\times[l_y,\lfloor\frac{l_y+r_y}{2}\rfloor]$、$[\lfloor\frac{l_x+r_x}{2}\rfloor+1,r_x]\times[l_y,\lfloor\frac{l_y+r_y}{2}\rfloor]$、$[l_x,\lfloor\frac{l_x+r_x}{2}\rfloor]\times[\lfloor\frac{l_y+r_y}{2}\rfloor+1,r_y]$ 和 $[\lfloor\frac{l_x+r_x}{2}\rfloor+1,r_x]\times[\lfloor\frac{l_y+r_y}{2}\rfloor+1,r_y]$。然后我们可以递归地计算出这四个子区间的 $g$ 值,然后将它们合并起来得到该节点的 $g$ 值。合并方法为取四个子区间的 $g$ 值的最大公约数。 查询时,我们从根节点开始,递归地查找覆盖询问区间的节点,并将这些节点的 $g$ 值取最大值。具体地,对于当前节点 $(x,y)$,如果它表示的区间与询问区间不相交,则直接返回 1。否则,如果它表示的区间完全包含询问区间,则返回该节点的 $g$ 值。否则,我们将询问区间分成四个子区间,并递归地查询每个子区间,然后将它们的 $g$ 值取最大公约数作为当前节点的 $g$ 值返回。 时间复杂度为 $O((n+m)\log^2(n+m))$,其中 $n$ 和 $m$ 分别为二维区间的行数和列数。空间复杂度为 $O((n+m)\log^2(n+m))$。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值