uva11889 - Benefit 数论

Benefit 

Recently Yaghoub is playing a new trick to sell some more. When somebody gives himA Tomans, hewho never has appropriate changes, asks forB Tomans such that lowest common multiple of A andB equals toC and he will pay back a round bill. Or otherwise take some snack instead of theremaining of his money. He believes that finding such a number is hard enough that dissuadesstudents from paying that.

You should write a program that help poor students giving the appropriate amount of money toYaghoub. Of course if there are several answers you go for students' benefit which is the lowest ofthem.

Input 

The first line begin with an integer T (T$ \le$100000), the number of tests. Each test that comes in aseparate line contains two integers A and C (1$ \le$A,C$ \le$107).

Output 

Print the lowest integer B such that LCM(A, B) = C in a single line. If no such integer exists, print "NO SOLUTION" instead. (Quotes for clarity)

Sample Input 

3
2 6
32 1760
7 16

Sample Output 

3
55
NO SOLUTION


  给出A,C=lcm(A,B),求最小的B,如果没有输出NO SOLUTION

  首先如果C不是A的倍数,那么肯定不行。

  A*B=gcd(A,B)*lcm(A,B),则C/A=B/gcd(A,B).

  设:

   lcm(A,B)=x^p1*y^p2*z^p3...

   gcd(A,B)=x^q1*y^q2*z^q3...

   A=x^m1*y^m2*z^m3...

   B=x^n1*y^n2*z^n3...

   B'=C/A=B/gcd(A,B)=x^k1*y^k2*z^k3...

   其中:

   p1=max(m1,n1),p2=max(m2,n2),p3=max(m3,n3)...

   q1=min(m1,n1),q2=min(m2,n2),q3=min(m3,n3)...

   k1=n1-q1,k2=n2-q2,k3=n3-q3...

  若x^m1和x^k1的gcd为1的话,说明m1=0或者是k1=0。如果m1=0,说明x这一项只有B有,B‘的这一项和B的这一项相等,则n1=k1。如果k1=0,n1=q1,又因为q1=min(m1,n1),所以n1<=m1,p1=m1,所以B’的x项为k1是满足的。如果x^m1和x^k1的gcd不为1,则m1!=0,k1!=0,n1=k1+q1=k1+min(m1,n1)=k1+m1,也就是m1<=n1,那么lcm的x这一项应该又B决定,p1=n1。由于B‘的x系数k1=n1-m1,所以还要把B'乘上x^m1。

  后面每一项都用这个方法。

  那么怎么快速乘上所有需要乘的各个系数的m次方呢?求gcd(A,B'),如果不为1,就把B’乘上这个gcd,A除以这个gcd,继续循环,直到gcd为1。这样就能把A比B‘多出的部分都乘上了。好神奇的方法。。。

  

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cstdlib>
#define INF 0x3f3f3f3f
#define MAXN 10010
#define MAXM 15
#define MAXNODE 4*MAXN
#define pii pair<int,int>
using namespace std;
int T,A,C;
int gcd(int a,int b){
    return a%b?gcd(b,a%b):b;
}
int main(){
    //freopen("in.txt","r",stdin);
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&A,&C);
        if(C%A) printf("NO SOLUTION\n");
        else{
            int B=C/A,t=1,g;
            while((g=gcd(A,B))!=1){
                t*=g;
                A/=g;
            }
            printf("%d\n",B*t);
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值