GCD & LCM Inverse
Time Limit: 2000MS | Memory Limit: 65536K |
Total Submissions: 7146 | Accepted: 1303 |
Description
Given two positive integers a and b, we can easily calculate the greatest common divisor (GCD) and the least common multiple (LCM) of a and b. But what about the inverse? That is: given GCD and LCM, finding a and b.
Input
The input contains multiple test cases, each of which contains two positive integers, the GCD and the LCM. You can assume that these two numbers are both less than 2^63.
Output
For each test case, output a and b in ascending order. If there are multiple solutions, output the pair with smallest a + b.
Sample Input
3 60
Sample Output
12 15
Source
POJ Achilles
題意:給你兩個數的最大公約數和最小公倍數,叫你求這兩個數,并且使得這兩個數的和最小。
因為數很大,是以必須用Pollard_Rho來分解素因子,将n除掉最大公約數後就是求n'能分解成兩個互素的數的和了,是以把每個素因子當作一個整體來處理。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <map>
#include <algorithm>
using namespace std;
typedef __int64 ll;
ll gcd(ll a,ll b)
{
return (b==0)?a:gcd(b,a%b);
}
ll Mulmod(ll a,ll b,ll n)
{
ll exp = a%n, res = 0;
while(b)
{
if(b&1)
{
res += exp;
if(res>n) res -= n;
}
exp <<= 1;
if(exp>n)
exp -= n;
b>>=1;
}
return res;
}
ll exp_mod(ll a,ll b,ll c)
{
ll k = 1;
while(b)
{
if(b&1)
k = Mulmod(k,a,c);
a = Mulmod(a,a,c);
b>>=1;
}
return k;
}
bool Miller_Rabbin(ll n, ll times)
{
if(n==2)return 1;
if(n<2||!(n&1))return 0;
ll a, u=n-1, x, y;
int t=0;
while(u%2==0){
t++;
u/=2;
}
srand(100);
for(int i=0;i<times;i++)
{
a = rand() % (n-1) + 1;
x = exp_mod(a, u, n);
for(int j=0;j<t;j++)
{
y = Mulmod(x, x, n);
if ( y == 1 && x != 1 && x != n-1 )
return false; //must not
x = y;
}
if( y!=1) return false;
}
return true;
}
ll Pollard_Rho(ll n,ll c)
{
ll x,y,d,i=1,k=2;
y = x = rand() % (n-1) + 1;
while(1)
{
i++;
x = (Mulmod(x,x,n) + c)%n;
d = gcd((x-y+n)%n,n);
if(d>1&&d<n)
return d;
if(x==y)
return n;
if(i==k)
{
k<<=1;
y = x;
}
}
}
ll factor[200],cnt;
void Find_factor(ll n,ll c)
{
if(n==1)
return;
if(Miller_Rabbin(n,6))
{
factor[cnt++] = n;
return;
}
ll p = n;
ll k = c;
while(p>=n)
p = Pollard_Rho(p,c--);
Find_factor(p,k);
Find_factor(n/p,k);
}
ll fac[1000];int s;
ll p,q,nn;
void dfs(ll count,int step)
{
if(step==s)
{
if(count+nn/count<p)
{
p=count+nn/count;
q=count;
}
return ;
}
ll sum;
sum=fac[step];
dfs(count*sum,step+1);
dfs(count,step+1);
}
int main()
{
ll m,n;
while(scanf("%I64d%I64d",&m,&n)!=EOF)
{
cnt = 0;
n/=m;
nn=n;
Find_factor(n,120);
sort(factor,factor+cnt);
s=0;
fac[0]=factor[0];
for(int i=1;i<cnt;i++)
{
if(factor[i]!=factor[i-1]) {s++;fac[s]=factor[i];}
else fac[s]*=factor[i];
}
p=1000000000000000000LL;//本來放在外面定義,腦殘了
dfs(1,0);
ll ww=nn/q;
if(q>ww) swap(q,ww);
printf("%I64d %I64d\n",m*q,m*ww);
}
}