2429 GCD & LCM Inverse 大整数分解质因数
2010-08-22 22:19
295 查看
GCD & LCM Inverse
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
Sample Output
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 3966 | Accepted: 680 |
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
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<ctime> #include<algorithm> //看情况选择下列两个 //#define bignum unsigned long long #define bignum unsigned __int64 using namespace std; //求a,b的最大公约数 bignum gcd(bignum a,bignum b) { return b==0?a:gcd(b,a%b); } //求a*b%c,因为a,b很大,所以要先将b写成二进制数,再加:例如3*7=3*(1+2+4); bignum mulmod(bignum a,bignum b,bignum c) { bignum cnt=0,temp=a; while(b) { if(b&1) cnt=(cnt+temp)%c; temp=(temp+temp)%c; b>>=1; } return cnt; } //求a^b%c,再次将b写成二进制形式,例如:3^7=3^1*3^2*3^4; bignum powmod(bignum a,bignum b,bignum c) { bignum cnt=1,temp=a; while(b) { if(b&1) cnt=mulmod(cnt,temp,c);//cnt=(cnt*temp)%c; temp=mulmod(temp,temp,c);//temp=(temp*temp)%c; b>>=1; } return cnt; } //Miller-Rabin测试n是否为素数,1表示为素数,0表示非素数 int pri[10]={2,3,5,7,11,13,17,19,23,29}; bool Miller_Rabin(bignum n) { if(n<2) return 0; if(n==2) return 1; if(!(n&1)) return 0; bignum k=0,m; m=n-1; while(m%2==0) m>>=1,k++;//n-1=m*2^k for(int i=0;i<10;i++) { if(pri[i]>=n) return 1; bignum a=powmod(pri[i],m,n); if(a==1) continue; int j; for(j=0;j<k;j++) { if(a==n-1) break; a=mulmod(a,a,n); } if(j<k) continue; return 0; } return 1; } //pollard_rho 大整数分解,给出n的一个非1因子,返回n是为一次没有找到 bignum pollard_rho(bignum C,bignum N) { bignum I, X, Y, K, D; I = 1; X = rand() % N; Y = X; K = 2; do { I++; D = gcd(N + Y - X, N); if (D > 1 && D < N) return D; if (I == K) Y = X, K *= 2; X = (mulmod(X, X, N) + N - C) % N; }while (Y != X); return N; } //找出N的最小质因数 bignum rho(bignum N) { if (Miller_Rabin(N)) return N; do { bignum T = pollard_rho(rand() % (N - 1) + 1, N); if (T < N) { bignum A, B; A = rho(T); B = rho(N / T); return A < B ? A : B; } } while(1); } //N分解质因数,这里是所有质因数,有重复的 bignum AllFac[1100]; int Facnum; void findrepeatfac(bignum n) { if(Miller_Rabin(n)) { AllFac[++Facnum]=n; return ; } bignum factor; do { factor=pollard_rho(rand() % (n - 1) + 1, n); }while(factor>=n); findrepeatfac(factor); findrepeatfac(n/factor); }
//求N的所有质因数,是除去重复的 bignum Fac[1100]; int num[1100]; int len; void FindFac(bignum n) { len=0; //初始化 memset(AllFac,0,sizeof(AllFac)); memset(num,0,sizeof(num)); Facnum=0; findrepeatfac(n); sort(AllFac+1,AllFac+1+Facnum); Fac[0]=AllFac[1]; num[0]=1; for(int i=2;i<=Facnum;i++) { if(Fac[len]!=AllFac[i]) { Fac[++len]=AllFac[i]; } num[len]++; } }
//dfs将key分解成两个互质的数的乘积,并且使这两个数和最小 /* bignum Fac[200]; int num[200]; int len;(0-len);*/ bignum res_a,res_b; bignum _min,key,com; void dfs(int cur,bignum val) { if(cur==len+1) { bignum a=val,b=key/val; if(gcd(a,b)==1) { a*=com,b*=com; if(a+b<_min) { _min=a+b; res_a=a<b ? a : b; res_b=a>b ? a : b; } } return ; } bignum s=1; for(int i=0;i<=num[cur];i++) { if(val*s>=_min) { return ; } dfs(cur+1,val*s); s*=Fac[cur]; } } int main () { srand(time(NULL)); bignum l,g; while(scanf("%I64u%I64u",&g,&l)!=EOF) { if(l==g) { printf("%I64u %I64u/n",g,l); continue; } //初始化 key=l/g; FindFac(key); //初始化 _min=(1<<63)-1;com=g; dfs(0,1); printf("%I64u %I64u/n",res_a,res_b); } return 0; }
相关文章推荐
- POJ 2429 GCD & LCM Inverse(大整数素因子分解+二进制枚举)
- poj2429 GCD & LCM Inverse 因数分解pollard_rho算法
- POJ2429_GCD & LCM Inverse【Miller Rabin素数测试】【Pollar Rho整数分解】
- POJ 2429 GCD & LCM Inverse (Pollard rho整数分解+dfs枚举)
- GCD & LCM Inverse POJ - 2429(Pollard rho整数分解+dfs)
- POJ 2429 GCD & LCM Inverse (整数分解,由gcd+lcm求a,b)
- POJ2429 GCD & LCM Inverse (大整数分解)
- POJ2429 GCD&LCM Inverse(整数分解,由GCD+LCM求a,b)
- 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 &amp; LCM Inverse(大数分解)
- POJ:2429-GCD & LCM Inverse(素数判断神题)(Millar-Rabin素性判断和Pollard-rho因子分解)
- POJ 2429 GCD & LCM Inverse (大整数素性测试与因式分解)
- POJ2429_GCD & LCM Inverse【Miller Rabin素数測试】【Pollar Rho整数分解】
- poj 2429 GCD & LCM Inverse(Miller_rabin 测试+pollard_rho大数分解)
- GCD & LCM Inverse POJ - 2429 Pollard_rho大数因子分解
- POJ 2429 GCD & LCM Inverse(Pollard_Rho+dfs)
- [POJ 2429] GCD & LCM Inverse
- POJ 2429 GCD & LCM Inverse Pollard_rho大数因子分解