http://poj.org/problem?id=2429
这题能1A感觉很好!Pollard_Rho 很神奇呀,能把这么大的数分解成素因子,然后dfs 找到其 ,lcm/gcd 的所有的因子就行了,取最优的答案
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define C 240
#define TIME 10
#define LL unsigned long long
using namespace std;
int cnt;
LL ans;
LL prime[1010],a,b;
LL gcd(LL a, LL b)
{
if(a==0) return 1;
if(a<0) return gcd(-a,b);
return b==0?a:gcd(b,a%b);
}
LL MultMod(LL a,LL b,LL n)
{
a%=n;
b%=n;
LL ret=0;
while(b)
{
if(b&1)
{
ret+=a;
if(ret>=n) ret-=n;
}
a=a<<1;
if(a>=n) a-=n;
b=b>>1;
}
return ret;
}
LL PowMod(LL a,LL n,LL m)
{
LL ret=1;
a=a%m;
while(n>=1)
{
if(n&1)
ret=MultMod(ret,a,m);
a=MultMod(a,a,m);
n=n>>1;
}
return ret;
}
bool Witness(LL a,LL n)
{
LL t=0,u=n-1;
while(!(u&1))
{
t++;
u/=2;
}
LL x0=PowMod(a,u,n);
for(int i=1; i<=t; i++)
{
LL x1=MultMod(x0,x0,n);
if(x1==1&&x0!=1&&x0!=(n-1))
return true;
x0=x1;
}
if(x0!=1)
return true;
return false;
}
bool Miller_Rabin(LL n,int t)
{
if(n==2) return true;
if((n&1)==0) return false;
srand(time(NULL));
for(int i=0; i<t; i++)
{
LL a=rand()%(n-1)+1;
if(Witness(a,n))
return false;
}
return true;
}
LL Pollard_Rho(LL n,LL c)
{
LL i=1,x=rand()%n,y=x,k=2;
while(1)
{
i++;
x=(MultMod(x,x,n)+c)%n;
LL d=gcd(y-x,n);
if(d!=1&&d!=n)
return d;
if(x==y)
return n;
if(i==k)
{
y=x;
k*=2;
}
}
}
void get_small(LL n,LL c)
{
if(n==1) return;
if(Miller_Rabin(n,TIME))
{
prime[cnt++]=n;
return;
}
LL p=n;
while(p>=n) p=Pollard_Rho(p,c--);
get_small(p,c);
get_small(n/p,c);
}
LL factor[20],ans1,ans2;
int fac_n;
void dfs(int id,LL mul)
{
//cout<<id<<" "<<mul<<endl;
if(id==fac_n)
{
if(ans1==-1||ans1+ans2 > a*mul+b/mul) ans1=a*mul,ans2=b/mul;
if(ans1>ans2) swap(ans1,ans2);
return;
}
dfs(id+1,mul*factor[id]);
dfs(id+1,mul);
}
int main()
{
while(scanf("%llu %llu",&a,&b)==2)
{
cnt=0;
get_small(b/a,C);
sort(prime,prime+cnt);
/*for(int i=0;i<cnt;i++)
cout<<prime[i]<<" ";
cout<<endl;*/
fac_n=0;
for(int i=0;i<cnt;i++)
{
factor[fac_n]=prime[i];
while(i<cnt-1&&prime[i]==prime[i+1]) factor[fac_n]*=prime[i++];
fac_n++;
}
/* for(int i=0;i<fac_n;i++)
cout<<factor[i]<<" ";
cout<<endl;*/
ans1=-1,ans2=-1;
dfs(0,1);
printf("%llu %llu\n",ans1,ans2);
}
return 0;
}
//3 60