POJ-2429 GCD & LCM Inverse

来源:互联网 发布:淘宝的账号被冻结 编辑:程序博客网 时间:2024/06/07 04:58

题目:

http://poj.org/problem?id=2429

题意:

给出gcd与lcm求原来两数,有多解时找出使得a+b最小的那个。

思路:

模版题,

lcm/gcd==(a/gcd)*(b/gcd).

所以求出lcm/gcd的所有质因子,自由组合成两组就是答案。

再dfs枚举所有情况找出a+b最小的情况。

代码:

#define N 112345#define T 10long long  n,m;long long  flag,ave,ans,res,len,ans1,ans2;long long mod_mul(long long a,long long b,long long n){    long long res = 0;    while(b)    {        if(b&1)    res = (res + a) % n;        a = (a + a) % n;        b >>= 1;    }    return res;}long long mod_exp(long long x,long long k,long long mod){    long long ans = 1;    while(k)    {        if(k & 1) ans = mod_mul(ans, x, mod);        x = mod_mul(x, x, mod);        k >>= 1;    }    return ans;}bool Miller_Rabin(long long n){    if(n == 2 || n == 3 || n == 5 || n == 7 || n == 11)    return true;    if(n == 1 || !(n%2) || !(n%3) || !(n%5) || !(n%7) || !(n%11))    return false;    long long x, pre, u;    int i, j, k = 0;    u = n - 1;    while(!(u&1))    {        k++;        u >>= 1;    }    for(i = 0; i < T; ++i)    {        x = rand()%(n-2) + 2;        if((x%n) == 0)            continue;        x = mod_exp(x, u, n);        pre = x;        for(j = 0; j < k; ++j)        {            x = mod_mul(x,x,n);            if(x == 1 && pre != 1 && pre != n-1)                return false;            pre = x;        }        if(x != 1)            return false;    }    return true;}long long factor[1000],factor2[1000];int sum,sum2;long long gcd(long long a,long long b){    if(a==0)return 1;    if(a<0) return gcd(-a,b);    while(b)    {        long long t=a%b;        a=b;        b=t;    }    return a;}long long Pollard_rho(long long x,long long c){    long long i=1,k=2;    long long x0=rand()%x;    long long y=x0;    while(1)    {        i++;        x0=(mod_mul(x0,x0,x)+c)%x;        long long d=gcd(y-x0,x);        if(d!=1&&d!=x) return d;        if(y==x0) return x;        if(i==k){y=x0;k+=k;}    }}void findfac(long long x){if(x==1)return ;    if(Miller_Rabin(x))    {        factor[sum++]=x;        return;    }    long long p=x;    while(p>=x)        p=Pollard_rho(p,rand()%(x-1)+1);    findfac(p);    findfac(x/p);}void dfs(int num,long long now){    if(sum2==num)    {        if(now&&ans>now+m/n/now)            ans=now+m/n/now,res=now;        return ;    }    dfs(num+1,now);    dfs(num+1,now*factor2[num]);}int main(){    long long i,j,k,kk,t,x,y,z;    srand((long long)time(0));    while(scanf("%lld%lld",&n,&m)!=EOF&&n)    {        x=m/n;        sum=0;        findfac(x);        ans=2e63;        sum2=0;        sort(factor,factor+sum);        factor2[0]=factor[0];        for(int i=0;i<sum;i++)        {            if(factor[i]==factor[i+1])                factor2[sum2]*=factor[i+1];            else                factor2[++sum2]=factor[i+1];        }        dfs(0,1);        if(res*n<m/res)            printf("%lld %lld\n",res*n,m/res);        else            printf("%lld %lld\n",m/res,res*n);    }    return 0;}







0 0
原创粉丝点击