poj 2429 GCD & LCM Inverse

来源:互联网 发布:matlab 创建cell数组 编辑:程序博客网 时间:2024/06/09 18:35

题意:给出两数的gcd和lcm,求乘积最小的两数。

解法:枚举lcm/gcd的因子,套模版。

 

#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#define time 12using namespace std;int p2[20];const int C=200;const long long max1 = (long long)pow((double)2,(double)62) ;long long min1;long long cnt, fac[20];long long gcd(long long x,long long y){    return y==0?x:gcd(y, x%y);}long long Mulmode(long long a,long long b,long long c){   //计算(a*b) mod n    long long ret = 0;    while(b){        if(b & 1)        ret = (ret + a) % c;        a = (a << 1) % c;        b = b >> 1;    }    return ret ;}long long powmode(long long a,long long b,long long c){ //计算(a^b) mod n    long long ret = 1;    while(b ){        if(b & 1)        ret = Mulmode(ret,a,c);        a = Mulmode(a,a,c);        b = b >> 1;    }    return ret ;}bool witness(long long a,long long n){   //以a为基对n进行Miller测试并实现二次探测    long long m,x,y;    int i,j = 0;    m = n - 1;    while(m % 2 == 0){        m  = m >> 1;        j ++;    }    x = powmode(a ,m ,n );    for(i = 1;i <= j ;i ++){        y = powmode(x,2,n);        if((y == 1) && (x != 1) && (x != n - 1))        return true;        x = y;    }    if(y != 1)    return true;    return false;}bool miller_rabin(long long n ,long long s){    long long a;    int i ;    if(n == 1)    return false ;    if(n == 2)    return true;    if(n % 2 == 0)    return false;    for(i = 1;i <= s; i ++){        a = rand() % (n - 1) + 1;        if(witness(a,n))        return false;    }    return true;}long long pollard_rho(long long n ,long long c ){    long long i,k,x,y,d;    i = 1;    k = 2;    x = rand() % n;    y = x;    while(true){        i ++ ;        x = (Mulmode(x, x, n) + c) % n;        d = gcd( y - x , n );        if( d > 1 && d < n ) return d;        if(y == x ) return n;        if(i == k ){            y = x;            k = k << 1;        }    }}void get_small(long long n,long long c){    long long m;    if(n == 1)    return;    if(miller_rabin(n,time)){        if(n < min1 )        min1 = n;        return;    }    m = n;    while(m == n )    m = pollard_rho(n, c--);    get_small(m , c);    get_small(n/m, c);}int main(){    long long a, b, n, ans;    p2[0]=1;    int i;    for(i=1; i<20; i++)    p2[i]=p2[i-1]*2;    while(scanf("%I64d%I64d",&a, &b)!=EOF){        n=b/a;        cnt=0;        ans=1;        while(n!=1&&!miller_rabin(n, time)){            min1=max1;            get_small(n, C);            fac[cnt]=1;            while(n%min1==0){                fac[cnt]*=min1;                n/=min1;            }            cnt++;        }        if(n>1){            fac[cnt++]=n;        }        n=b/a;        int k=p2[cnt]-1;        while(k>=0){            int t=k;            long long tmp=1;            for(i=0; i<cnt; i++){                if(t&1)                    tmp*=fac[i];                t>>=1;            }            if(n/tmp<tmp)tmp=n/tmp;            if(tmp>ans)ans=tmp;            k--;        }        printf("%lld %lld\n", ans*a, n/ans*a);    }    return 0;}


 

原创粉丝点击