GCD and LCM Aizu - 0005(辗转相除)+GCD LCM Inverse POJ - 2429(java或【Miller Rabin素数測试】+【Pollar Rho整数分解】)
題目:GCD and LCM Aizu - 0005
Write a program which computes the greatest common divisor (GCD) and the least common multiple (LCM) of given a and b.
Input
Input consists of several data sets. Each data set contains a and b separated by a single space in a line. The input terminates with EOF.
Constraints
0 < a, b ≤ 2,000,000,000
LCM(a, b) ≤ 2,000,000,000
The number of data sets ≤ 50
Output
For each data set, print GCD and LCM separated by a single space in a line.
Sample Input
8 6
50000000 30000000
Output for the Sample Input
2 24
10000000 150000000
分析:
求最大公約數(shù)和最小公倍數(shù)。。。
AC代碼:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; typedef long long ll; ll n,m; ll gcd(ll x,ll y) {return y==0?x:gcd(y,x%y); } int main() {while(~scanf("%lld%lld",&n,&m)){ll a=gcd(n,m);printf("%lld %lld\n",a,n*m/a);}return 0; }題意:
給你兩個數(shù)a和b的最大公約數(shù)和最小公倍數(shù)。求a和b(當中在滿足條件的情況下。使a+b盡量小)
題目: LCM Inverse POJ - 2429
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
分析:
作者顯然高估了讀者的數(shù)學修養(yǎng),我對數(shù)論一點都不熟悉,這題光靠前面介紹的一點數(shù)論皮毛無從下手,還是看了人家的代碼才知道要用Rabin-Miller強偽素數(shù)測試和Pollard r因數(shù)分解算法。
基本思路是
(1)、(a / gcd) * (b / gcd) = lcm / gcd ,所以需要分解lcm / gcd 。將其分解為互質(zhì)的兩個數(shù),如果這兩個數(shù)之和最小,那么乘上gcd就是所求的答案。
(2)、但是題目數(shù)據(jù)太大,需要一個高效的素數(shù)檢測算法,所以采用Rabin-Miller強偽素數(shù)測試
(3)、然后分解成質(zhì)因子的n次方之積,從這些n次方中挑選一些作為x,剩下的作為y。枚舉x和y的所有可能,找出最小值。
Rabin-Miller強偽素數(shù)測試和Pollard r因數(shù)分解算法
AC代碼:
此代碼并非我所寫,我只理解了,由于時間緊迫,若有時間,回來鉆研,這里放AC模板。
#include<stdio.h> #include<stdlib.h> #include<time.h> #include<math.h> #include<algorithm> using namespace std; typedef long long ll; #define MAX_VAL (pow(2.0,60)) //miller_rabbin素性測試 ll mod_mul(ll x,ll y,ll mo) {ll t,T,a,b,c,d,e,f,g,h,v,ans;T = (ll)(sqrt(double(mo)+0.5));t = T*T - mo;a = x / T;b = x % T;c = y / T;d = y % T;e = a*c / T;f = a*c % T;v = ((a*d+b*c)%mo + e*t) % mo;g = v / T;h = v % T;ans = (((f+g)*t%mo + b*d)% mo + h*T)%mo;while(ans < 0)ans += mo;return ans; }ll mod_exp(ll num,ll t,ll mo) {ll ret = 1, temp = num % mo;for(; t; t >>=1,temp=mod_mul(temp,temp,mo))if(t & 1)ret = mod_mul(ret,temp,mo);return ret; }bool miller_rabbin(ll n) {if(n == 2)return true;if(n < 2 || !(n&1))return false;int t = 0;ll a,x,y,u = n-1;while((u & 1) == 0){t++;u >>= 1;}for(int i = 0; i < 50; i++){a = rand() % (n-1)+1;x = mod_exp(a,u,n);for(int j = 0; j < t; j++){y = mod_mul(x,x,n);if(y == 1 && x != 1 && x != n-1)return false;x = y;}if(x != 1)return false;}return true; } //PollarRho大整數(shù)因子分解 ll minFactor; ll gcd(ll a,ll b) {if(b == 0)return a;return gcd(b, a % b); }ll PollarRho(ll n, int c) {int i = 1;srand(time(NULL));ll x = rand() % n;ll y = x;int k = 2;while(true){i++;x = (mod_exp(x,2,n) + c) % n;ll d = gcd(y-x,n);if(1 < d && d < n)return d;if(y == x)return n;if(i == k){y = x;k *= 2;}} } ll ans[1100],cnt; void getSmallest(ll n, int c) {if(n == 1)return;if(miller_rabbin(n)){ans[cnt++] = n;return;}ll val = n;while(val == n)val = PollarRho(n,c--);getSmallest(val,c);getSmallest(n/val,c); } ll a,b,sq; void choose(ll s,ll val) {if(s >= cnt){if(val > a && val <= sq)a = val;return;}choose(s+1,val);choose(s+1,val*ans[s]); }int main() {int T;ll G,L;while(~scanf("%lld%lld",&G,&L)){if(L == G){printf("%lld %lld\n",G,L);continue;}L /= G;cnt = 0;getSmallest(L,200);sort(ans, ans+cnt);int j = 0;for(int i = 1; i < cnt; i++){while(ans[i-1] == ans[i] && i < cnt)ans[j] *= ans[i++];if ( i < cnt )ans[++j] = ans[i];}cnt = j+1;a = 1;sq = (ll)sqrt(L+0.0);choose(0,1);printf("%lld %lld\n",a*G,L/a*G);}return 0; }JAVA
import java.util.Scanner;public class Main {static long gcd(long a,long b){long tmp;while (b!=0){tmp = b;b = a % b;a = tmp;}return a;}public static void main(String args[]){Scanner cin = new Scanner(System.in);long a,b,c,i;while (cin.hasNext()){a = cin.nextLong();b = cin.nextLong();c = b/a;for(i=(long)Math.sqrt(c); i>=1; i--){if(c%i==0&&gcd(i,c/i)==1){System.out.println((a*i)+" "+(b/i));break;}}}} }總結(jié)
以上是生活随笔為你收集整理的GCD and LCM Aizu - 0005(辗转相除)+GCD LCM Inverse POJ - 2429(java或【Miller Rabin素数測试】+【Pollar Rho整数分解】)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 糙米热量高为什么可以减肥
- 下一篇: Prime Number Aizu -