1. 程式人生 > >POJ 2429 long long 質因數分解

POJ 2429 long long 質因數分解

cst factor pro calc can 返回 a + b names 素數

GCD & LCM Inverse
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 16206 Accepted: 3008

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 題意: 給出gcd和lcm求和最小的兩個數a,b 代碼:
//a*b=gcd*lcm,x=a/gcd,y=b/gcd,s=lcm/gcd => x*y=s;
//想要a+b小 => x*gcd+y*gcd小 => x*y小,x和y越接近sqrt(S)時x+y越小(對勾函數)
//所以求出s的素因子然後搞一搞就行了
#include<iostream>
#include<cstdio>
#include<cstring>
#include
<cmath> #include<cstdlib> #include<ctime> #include<algorithm> using namespace std; typedef long long ll; const int S=20;//隨機算法判定次數,S越大判錯概率越小 //計算(a*b)%c;a,b,c<2^63 ll mult_mod(ll a,ll b,ll c){ a%=c; b%=c; ll ret=0; while(b){ if(b&1){ ret+=a; ret%=c; } a<<=1; if(a>=c) a%=c; b>>=1; } return ret; } //計算(x^n)%c ll pow_mod(ll x,ll n,ll c){ if(n==1) return x%c; x%=c; ll tmp=x; ll ret=1; while(n){ if(n&1) ret=mult_mod(ret,tmp,c); tmp=mult_mod(tmp,tmp,c); n>>=1; } return ret; } //以a為基,n-1=x*2^t a^(n-1)=1(mod n) 驗證n是不是合數 //一定是合數返回true,不一定返回false bool check(ll a,ll n,ll x,ll t){ ll ret=pow_mod(a,x,n); ll last=ret; for(int i=1;i<=t;i++){ ret=mult_mod(ret,ret,n); if(ret==1&&last!=1&&last!=n-1) return true; last=ret; } if(ret!=1) return true; return false; } // Miller_Rabin()算法素數判定 //是素數返回true.(可能是偽素數,但概率極小) //合數返回false; bool Miller_Rabin(ll n){ if(n<2) return false; if(n==2) return true; if((n&1)==0) return false; ll x=n-1; ll t=0; while((x&1)==0){ x>>=1; t++; } for(int i=0;i<S;i++){ ll a=rand()%(n-1)+1; if(check(a,n,x,t)) return false; } return true; } ll gcd(ll a,ll b){ if(a==0) return 1; if(a<0) return gcd(-a,b); while(b){ ll t=a%b; a=b; b=t; } return a; } //Pollard_rho質因數分解算法 ll factor[1000];//質因數分解結果(無序的) int tot;//質因數的個數,數組下標從0開始 ll Pollard_rho(ll x,ll c){ ll i=1,k=2; ll x0=rand()%x; ll y=x0; while(1){ i++; x0=(mult_mod(x0,x0,x)+c)%x; ll d=gcd(y-x0,x); if(d!=1&&d!=x) return d; if(y==x0) return x; if(i==k){ y=x0; k+=k; } } } //對n進行素因子分解 void findfac(ll n){ if(Miller_Rabin(n)){//素數 factor[tot++]=n; return; } ll p=n; while(p>=n) p=Pollard_rho(p,rand()%(n-1)+1); findfac(p); findfac(n/p); } ll ans,fa[100]; int nu; void dfs(int st,ll x,ll maxx) { if(st>nu){ if(x<=maxx&&x>ans) ans=x; return; } dfs(st+1,x,maxx); dfs(st+1,x*fa[st],maxx); } int main() { //srand(time(NULL)); ll a,b; while(scanf("%lld%lld",&a,&b)==2){ if(a==b){ printf("%lld %lld\n",a,b); continue; } tot=nu=0; ll s=b/a; findfac(s); sort(factor,factor+tot); fa[0]=factor[0]; for(int i=1;i<tot;i++){//合並相同的素因子 if(factor[i]==factor[i-1]) fa[nu]*=factor[i]; else fa[++nu]=factor[i]; } ll x=(ll)sqrt(s*1.0); ans=1; dfs(0,1,x); printf("%lld %lld\n",ans*a,s/ans*a); } return 0; }

POJ 2429 long long 質因數分解