令x=lcm/gcd
将x分解质因数->Pollard rho方法
枚举将x分解为两个互素的数相乘
代码:
#include<ctime>
#include<iostream>
#include<fstream>
using namespace std;
long long factor[1000],fac_top = -1;
//计算两个数的gcd
long long gcd(long long a,long long b)
{
if(a==0)
return b;
long long c;
while(b!=0)
{
c=b;
b=a%b;
a=c;
}
return a;
}
//ret = (a*b)%n (n<2^62)
long long muti_mod(long long a,long long b,long long n)
{
long long 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;
}
// ret = (a^b)%n
long long mod_exp(long long a,long long p,long long m)
{
long long exp=a%m, res=1; //
while(p>1)
{
if(p&1)//
res=muti_mod(res,exp,m);
exp = muti_mod(exp,exp,m);
p>>=1;
}
return muti_mod(res,exp,m);
}
//miller-rabin法测试素数, time 测试次数
bool miller_rabin(long long n, long long times)
{
if(n==2)return 1;
if(n<2||!(n&1))return 0;
long long a, u=n-1, x, y;
int t=0;
while(u%2==0){
t++;
u/=2;
}
srand(time(0));
for(int i=0;i<times;i++)
{
a = rand() % (n-1) + 1;
x = mod_exp(a, u, n);
for(int j=0;j<t;j++)
{
y = muti_mod(x, x, n);
if ( y == 1 && x != 1 && x != n-1 )
return false; //must not
x = y;
}
if( y!=1) return false;
}
return true;
}
long long pollard_rho(long long n,int c)
{//找出一个因子
long long x,y,d,i = 1,k = 2;
srand(time(0));
x = rand()%(n-1)+1;
y = x;
while(true) {
i++;
x = (muti_mod(x,x,n) + c) % n;
d = gcd(y-x, n);
if(1 < d && d < n)return d;
if( y == x) return n;
if(i == k) {
y = x;
k <<= 1;
}
}
}
void findFactor(long long n,int k)
{//二分找出所有质因子,存入factor
if(n==1)return;
if(miller_rabin(n, 10))
{
factor[++fac_top] = n;
return;
}
long long p = n;
while(p >= n)
p = pollard_rho(p,k--);//k值变化,防止死循环
findFactor(p,k);
findFactor(n/p,k);
}
long long a[1000];
long long m,minx,ans;
int cmp(const void *a,const void *b){
return *(long long *)a-*(long long *)b;
}
void dfs(long long s,long long num,long long t){
if(s==m+1)
{
if(minx==-1||(num+t/num<minx))
{
minx=num+t/num;
ans=num;
}
return;
}
dfs(s+1,num*a[s],t);
dfs(s+1,num,t);
}
void solve(){
qsort(factor,fac_top+1,sizeof(long long),cmp);
a[0]=factor[0];
long long i;
for(i=0;i<fac_top;i++)
if(factor[i]==factor[i+1])
{
a[m]*=factor[i+1];
}
else
{
m++;
a[m]=factor[i+1];
}
}
int main()
{
long long s,t,n;
// ifstream cin("in.txt");
while(cin>>s>>t)
{
n=t/s;
if(s==t)
{
cout<<s<<' '<<t<<endl;
continue;
}
minx=-1;
m=0;
fac_top = -1;
findFactor(n,107);
solve();
dfs(0,1,n);
if(ans>n/ans) ans=n/ans;
cout<<s*ans<<' '<<s*(n/ans)<<endl;
}
return 0;
}