poj2429:因数分解+搜索

时间:2023-03-09 05:46:25
poj2429:因数分解+搜索

题意:给定gcd(a,b)和lcm(a,b) 求使得a+b最小的 a,b

思路:结合算数基本定理中 gcd lcm的质因子表示形式

把lcm(a,b)质因数分解 以后 通过dfs找到 a+b最小的a b即可

#include <iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
using namespace std;
long long fac[];
int nf;
long long a,b;
long long x,y;
long long mk;
long long ans1,ans2;
long long gcd(long long a,long long b)
{
return b?gcd(b,a%b):a;
}
long long random(long long n)
{
return (long long)(rand()%(n-)+);
}
long long multimod(long long a,long long b,long long m)//a*b%m
{
long long res=;
while(b>)
{
if(b&)
res=(res+a)%m;
b>>=;
a=(a<<)%m;
}
return res;
}
long long quickmod(long long a,long long b,long long m) //a^b%m
{
long long res=;
while(b>)
{
if(b&)
res=multimod(res,a,m);
b>>=;
a=multimod(a,a,m);
}
return res;
}
int check(long long a,long long n,long long x,long long t)
{
long long res=quickmod(a,x,n);
long long last=res;
for(int i=;i<=t;i++)
{
res=multimod(res,res,n);
if(res==&&last!=&&last!=n-) return ;
last=res;
}
if(res!=) return ;
return ;
} int primetest(long long n)
{
if(n<)return ;
if(n==)return ;
if((n&)==) return ;
long long x=n-;
long long t=;
while((x&)==){x>>=;t++;}
for(int i=;i<;i++)
{
long long a=random(n);
if(check(a,n,x,t))
return ;
}
return ;
} long long pollardrho(long long n,long long c)
{
long long x,y,d,i,k;
i=;k=;
x=random(n);
y=x;
while()
{
i++;
x=(multimod(x,x,n)+c)%n;
long long tmp=y-x>=?y-x:x-y;
d=gcd(tmp,n);
if(d>&&d<n)
return d;
if(y==x)
return n;
if(i==k)
{
y=x;
k+=k;
}
}
}
void findfac(long long n)
{
if(n==)
return;
if(primetest(n))
{
fac[nf++]=n;
return;
}
long long p=n;
while(p>=n)
p=pollardrho(n,random(n-));
findfac(p);
findfac(n/p);
}
void dfs(long long x,long long y,int s,long long pre)
{
while(fac[s]==pre&&(s<nf))
s++; //因子判重
if(s==nf)
{
if(x+y<mk)
{
mk=x+y;
ans1=x;
ans2=y;
}
return;
}
long long i=,j=;
long long a1=a,b1=b;
while(a1%fac[s]==)
{
a1/=fac[s];
}
while(b1%fac[s]==)
{
b1/=fac[s];
}
i=a/a1;
j=b/b1;
dfs(x*i,y*j,s+,fac[s]);
dfs(x*j,y*i,s+,fac[s]);
return;
}
int main()
{ while(scanf("%I64d %I64d",&a,&b)!=EOF)
{
nf=;
findfac(b);
mk=;
sort(fac,fac+nf);
dfs(,,,-);
if(ans1>ans2)
swap(ans1,ans2);
printf("%I64d %I64d\n",ans1,ans2);
}
}