POJ2429 GCD&LCM Inverse(整数分解,由GCD+LCM求a,b)
2013-08-14 21:20
543 查看
POJ2429 GCD&LCM Inverse(整数分解,由GCD+LCM求a,b)
分类: 数论2013-02-1222:00 180人阅读 评论(1) 收藏 举报
题目:GCD & LCM Inverse
题意:给你两个数G和L分别是a,b的最大公约数和最小公倍数,求a,b。(有多组a,b的情况下取a+b最小的)
分析:由于 G和L分别是a,b的最大公约数和最小公倍数,那么G一定整除L,否则就没有解了。
进一步可以知道L/G的素因子分解式中,同一项不会同时出现在a,b中,因为相同的在G中已经除掉了.
那么有:
,所以我们现在只需要枚举L/G的约数,枚举的一个x在a中,那么另一个(L/G)/x就是在b中,但是我们知道
,
,所以思路就是对L/G先分解,因为这个数很大,所以就用Pollard-rho分解法吧,分解之后,利用
dfs找因子,然后每找到一个就判断一次来记录a+b最小的,然后就分析完毕。
[cpp] view
plaincopy
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
#define LL unsigned long long
const int Times=10;
const LL INF=(LL)1<<61;
const int N=550;
LL n,m,ct,cnt,mini,mina,minb,ans;
LL fac
,num
;
LL gcd(LL a,LL b)
{
return b? gcd(b,a%b):a;
}
LL multi(LL a,LL b,LL m)
{
LL ans=0;
while(b)
{
if(b&1)
{
ans=(ans+a)%m;
b--;
}
b>>=1;
a=(a+a)%m;
}
return ans;
}
LL quick_mod(LL a,LL b,LL m)
{
LL ans=1;
a%=m;
while(b)
{
if(b&1)
{
ans=multi(ans,a,m);
b--;
}
b>>=1;
a=multi(a,a,m);
}
return ans;
}
bool Miller_Rabin(LL n)
{
if(n==2) return true;
if(n<2||!(n&1)) return false;
LL a,m=n-1,x,y;
int k=0;
while((m&1)==0)
{
k++;
m>>=1;
}
for(int i=0;i<Times;i++)
{
a=rand()%(n-1)+1;
x=quick_mod(a,m,n);
for(int j=0;j<k;j++)
{
y=multi(x,x,n);
if(y==1&&x!=1&&x!=n-1) return false;
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(true)
{
i++;
x=(multi(x,x,n)+c)%n;
d=gcd((y-x+n)%n,n);
if(1<d&&d<n) return d;
if(y==x) return n;
if(i==k)
{
y=x;
k<<=1;
}
}
}
void find(LL n,int c)
{
if(n==1) return;
if(Miller_Rabin(n))
{
fac[ct++]=n;
return ;
}
LL p=n;
LL k=c;
while(p>=n) p=Pollard_rho(p,c--);
find(p,k);
find(n/p,k);
}
void dfs(LL c,LL value)
{
LL s=1,a,b;
if(c==cnt)
{
a=value;
b=ans/a;
if(gcd(a,b)==1)
{
a*=n;
b*=n;
if(a+b<mini)
{
mini=a+b;
mina=a;
minb=b;
}
}
return ;
}
for(LL i=0;i<=num[c];i++)
{
if(s*value>mini) return;
dfs(c+1,s*value);
s*=fac[c];
}
}
int main()
{
while(~scanf("%llu%llu",&n,&m))
{
if(n==m)
{
printf("%llu %llu\n",n,m);
continue;
}
mini=INF;
ct=cnt=0;
ans=m/n;
find(ans,120);
sort(fac,fac+ct);
num[0]=1;
int k=1;
for(LL i=1;i<ct;i++)
{
if(fac[i]==fac[i-1])
++num[k-1];
else
{
num[k]=1;
fac[k++]=fac[i];
}
}
cnt=k;
dfs(0,1);
if(mina>minb) swap(mina,minb);
printf("%llu %llu\n",mina,minb);
}
return 0;
}
相关文章推荐
- GCD & LCM Inverse POJ - 2429(Pollard rho整数分解+dfs)
- POJ 2429 GCD & LCM Inverse(大整数素因子分解+二进制枚举)
- POJ 2429 GCD & LCM Inverse (Pollard rho整数分解+dfs枚举)
- POJ 2429 GCD & LCM Inverse (整数分解,由gcd+lcm求a,b)
- POJ2429_GCD & LCM Inverse【Miller Rabin素数测试】【Pollar Rho整数分解】
- POJ2429 GCD & LCM Inverse (大整数分解)
- POJ 2429 GCD &amp; LCM Inverse(大数分解)
- POJ 2429 GCD & LCM Inverse (大整数素性测试与因式分解)
- GCD & LCM Inverse POJ - 2429 Pollard_rho大数因子分解
- POJ 2429 GCD & LCM Inverse(素数判定Miller-Rabin+素因子分解Pollard-rho)
- poj 2429 GCD & LCM Inverse(拉宾米勒测试+大数分解+dfs)
- POJ 2429 GCD & LCM Inverse Pollard Rho大数分解法
- poj 2429 GCD & LCM Inverse(Miller_rabin 测试+pollard_rho大数分解)
- POJ:2429-GCD & LCM Inverse(素数判断神题)(Millar-Rabin素性判断和Pollard-rho因子分解)
- poj2429 GCD & LCM Inverse 因数分解pollard_rho算法
- 2429 GCD & LCM Inverse 大整数分解质因数
- <模板>(Miller-Rabin和Pollard_rho算法)poj 2429 GCD & LCM Inverse (数论)
- Mathematics:GCD & LCM Inverse(POJ 2429)
- [POJ 2429] GCD & LCM Inverse
- POJ 2429 GCD & LCM Inverse Pollard_Rho大数分解+Miller_Rabin