UVa 11889 Benefit (数论)

UVa 11889 Benefit


题目大意:

给两个整数A和C,求最小的整数B使得lcm(A,B)=C.若无解,输出”NO SOLUTION”(不含引号).

题目分析:

显然可知,若C%A!=0,则无解.
对于有解的情况,如下

A=gp1B=gp2C=gp1p2

要使 lcm(A,B)=C ,则 p1p2 互质.
要使 B 尽可能小,因为p2=C/A为定值,那么 g 需要尽可能小.
因为A=gp1是定值,那么 p1 就要尽可能大.
所以题目转化为了在 p1 p2 互质的前提下,使得 p1 尽可能大.

可以选择将 p2 用唯一分解定理分解成多个质因数相乘.那么对于 p2 所包含的质因数, p1 是不能选的,只能将其放在 g <script type="math/tex" id="MathJax-Element-2012">g</script>中.

代码:

#include<cmath>
#include<cstdio>
#include<iostream>
#include<algorithm>

using namespace std;

const int maxn=10000000;
const int maxp=700000;

int not_pri[maxn+1],pri[maxp+1],pcnt;

void init(int n)
{
    for(int i=2;i<=n;i++) {
        if(!not_pri[i]) pri[pcnt++]=i;
        for(int j=0;j<pcnt&&1ll*pri[j]*i<=n;j++) {
            not_pri[pri[j]*i]=1;
            if(i%pri[j]==0) break;
        }
    }
}

int main()
{
    init(maxn);
    int T;
    scanf("%d",&T);
    while(T--) {
        int A,C;
        scanf("%d%d",&A,&C);
        if(C%A) {
            printf("NO SOLUTION\n");
            continue;
        }
        int p=C/A,g=1;
        int m=sqrt(p),t=p;
        for(int i=0;pri[i]<=m&&t!=1;i++)
            if(t%pri[i]==0) {
                while(t%pri[i]==0) t/=pri[i];
                while(A%pri[i]==0) A/=pri[i],g*=pri[i];//因为B中有此质因数,故舍去,放在g中 
            }
        if(t>1) while(A%t==0) A/=t,g*=t;//t还剩下时,有且仅有一个大于√p,且t为素数,也判断需不需要舍去 
        printf("%d\n",p*g);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值