P8443 gcd.

发布时间 2023-07-27 14:39:23作者: 星河倒注

与你借星火,容我题山河。


一.题目大意

原题要我们求
\(\operatorname{gcd}\left(\left\lfloor\frac{l}{x}\right\rfloor,\left\lfloor\frac{l+1}{x}\right\rfloor, \cdots,\left\lfloor\frac{r}{x}\right\rfloor\right)\) ,

\(\left\lfloor\frac{l}{x}\right\rfloor,\left[\frac{l+1}{x}\right\rfloor, \cdots,\left\lfloor\frac{r}{x}\right\rfloor\) ,其实都是整数,所以这题就是求 \(r-l+1\) 个整数的最大公约数。


二.暴力算法

直接求两两之间的公约数,库函数里有函数 gcd ,很好写。

#include<algorithm> //配套头文件
int gcd(int a,int b){
	return __gcd(a,b);
}

三.正解

看到这种数据范围,显然是数学题,小学学过,两个相邻的数的最大公约数是 1 ,下面给出一个例子。

就拿 4 和 5 举例,假设它们的最大公约数为 Y,那么它们的最小公倍数为 \({\frac{20}{Y} }\) ,我们知道 4 和 5 的最小公倍数为 20 ,所以 Y 为 1 。

因为 区间{l,r} 为连续整数,所以 \(\left\lfloor l\right\rfloor,\left\lfloor l+1\right\rfloor, \cdots,\left\lfloor r\right\rfloor\) 也是连续整数。把 \(\left\lfloor l\right\rfloor,\left\lfloor l+1\right\rfloor, \cdots,\left\lfloor r\right\rfloor\) 同时除以 x ,得 \(\operatorname{gcd}\left(\left\lfloor\frac{l}{x}\right\rfloor,\left\lfloor\frac{l+1}{x}\right\rfloor, \cdots,\left\lfloor\frac{r}{x}\right\rfloor\right)\) 之中任意两个连续的数要么相等。要么差 1 ,不可能相差 2 及以上。

只要有任意两个数差 1 ,就代表有相邻的数,输出 \(1\)
只要最开始的数和结尾的数不一样就肯定是这种情况,因为不可能有两个数相差 2 及以上。

如果都一样,输出那一个数就行了!

具体实现

#include<bits/stdc++.h> //万能头
using namespace std;
long long t;//数据组数
long long l,r,x;

int main(){
	cin>>t;
	for(int i=1;i<=t;i++){
		cin>>l>>r>>x;
		if(l==r) cout<<l/x<<endl; //只有一个数
		else{
			if(l/x!=r/x) cout<<1<<endl; //如果l/x!=r/x,肯定中途有两个数相邻(可能出现多次)
			else cout<<l/x<<endl; //全部相等
		}
	}
	return 0;
}

第一次写题解。有一篇没过。 求管理员大大过。