【2019春季SMUACM省赛预备队员选拔赛 - 第一场】A.签到题

 

废话

这个是集训队安神还有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~\sqrt{z} 范围内的素数取模枚举比对,如果有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);            
        }
    }
}

 

 

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值