『题解』Luogu P8443 gcd
题目大意
给定 \(l,r,x\),求 \(\gcd\left(\left\lfloor\dfrac{l}{x}\right\rfloor,\left\lfloor\dfrac{l+1}{x}\right\rfloor,\dots\left\lfloor\dfrac{r}{x}\right\rfloor\right)\)。
特别的,我们定义一个正整数的最大公约数是它本身。
多组数据。
思路
我们先来试着把数套进这个柿子里,找找规律。
例如第一组样例:
\(l=3,r=6,x=1\)。
我们试着套进去:
我们发现,需要参与计算的数是单调上升的,且都是相邻的。
那么我们根据一条性质:相邻的数一定互质。
可以得出这个答案为 \(1\)。
接着我们套第二组数据 \(l=8,r=11,x=4\),发现是这样的:\(\gcd(2,2,2,2)\)。
答案即为 \(2\)。
那如果我们把 \(r\) 改成 \(12\) 呢?
那么就多了个 \(\left\lfloor\dfrac{12}{4}\right\rfloor=3\),刚好是 \(2+1\),与 \(2\) 互质,答案就从 \(2\) 变为了 \(1\)。
我们可以发现,参与 \(\gcd\) 的数由这样三部分组成:
-
首端:一组最少 \(1\) 个,最多 \(x\) 个相同的数,这个数即为 \(\left\lfloor\dfrac{l}{x}\right\rfloor\)。
-
中间:若干组由 \(x\) 个相同的数组成的数列。每组中的数为上一组中的数加一。可以没有这个部分。
-
末尾:同首端。如果没有中间部分,也没有这个部分。
为什么就这么肯定由这几部分组成呢?
先来看看 \(l=0\) 到 \(r=20\) 每个数除以 \(x=4\) 的结果:
\(0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5\)。
很容易从中看出规律来。正如上所述。
显然,只要有两个不同的数,答案就一定为 \(1\)。
于是我们就可以直接判断 \(\left\lfloor\dfrac{l}{x}\right\rfloor\) 和 \(\left\lfloor\dfrac{r}{x}\right\rfloor\) 是否相等即可。
若相等,则整个数列里的数都相同,显然它们的最大公约数即为它们本身。
代码
#include <iostream>
using namespace std;
int t;
long long l,r,x;
int main(){
scanf("%d",&t);
while(t--){
scanf("%lld%lld%lld",&l,&r,&x);
printf("%lld\n",l/x!=r/x ? 1 : l/x);
}
return 0;
}