废话
这个是集训队安神还有yjh学长给出的题!辛苦!!
昨天刚看了点数论,结果还是凄惨签到失败,结束后改了一个字母然后绿Acccccc..
可怜小刘在线哭泣.
题目
给定mm个询问,每个询问给定两个正整数X,ZX,Z,问最小的正整数YY满足LCM(X,Y)=ZLCM(X,Y)=Z,如果不存在这样的YY,就输出−1−1。
LCM(X,Y)LCM(X,Y)表示XX和YY的最小公倍数。
数据范围:
1≤m≤105,1≤X,Z≤109
虚伪的只有自己能看懂的题解?
设
x=a*b,y=b*c,
gcd(x,y)=b
z=lcm(x,y)=(x*y)/gcd(x,y);
我...一开始想的是分解成标准分解式(全素数)的做法,欧拉筛了一下素数,然后从1~ 范围内的素数取模枚举比对,如果有z里面这个素数的指数大于x里面,y*=(这个素数),最后y就是正解,然好rererererererererererere
改了个把小时真的改不出来删了又佛系重写,没想到佛过了..
我举的例子是12 8 24 = 6 2 12 = 3 1 6
可以算上个规律?(咳)
然后不停的除一个值应该就可以,这里是gcd(a,b)
代码
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
int gcd(int a,int b){
if(b>a){int c=b;b=a;a=c;}
if(b==0) return a;
return gcd(b,a%b);
}//lcm和gcd是一对!见lcm想gcd
int m,x,y,z;
int main(){
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d %d",&x,&z);
if(z<x||z%x!=0) printf("-1\n");
else if(x==1) printf("%d\n",z);//先特判一眼特殊情况
else {
y=z/x;
int a=x,b=y,c=z;
if(((y*x)/gcd(y,x))==z) ;
else while(1){
int k = gcd(a,b);
if(((a*b)/gcd(a,b))==c) break;
a/=k;
c/=k;
y*=k;
}
printf("%d\n",y);
}
}
}