poj2429:因数分解+搜索

题意:给定gcd(a,b)和lcm(a,b) 求使得a+b最小的 a,b

思路:结合算数基本定理中 gcd lcm的质因子表示形式

把lcm(a,b)质因数分解 以后 通过dfs找到 a+b最小的a b即可

#include <iostream>

#include<stdio.h>

#include<algorithm>

#include<math.h>

using namespace std;

long long fac[100];

int nf;

long long a,b;

long long x,y;

long long mk;

long long ans1,ans2;

long long gcd(long long a,long long b)

{

    return b?gcd(b,a%b):a;

}

long long random(long long n)

{

    return (long long)(rand()%(n-1)+1);

}

long long multimod(long long a,long long b,long long m)//a*b%m

{

    long long res=0;

    while(b>0)

    {

        if(b&1)

            res=(res+a)%m;

        b>>=1;

        a=(a<<1)%m;

    }

    return res;

}

long long quickmod(long long a,long long b,long long m) //a^b%m

{

    long long res=1;

    while(b>0)

    {

        if(b&1)

            res=multimod(res,a,m);

        b>>=1;

        a=multimod(a,a,m);

    }

    return res;

}

int check(long long a,long long n,long long x,long long t)

{

    long long res=quickmod(a,x,n);

    long long last=res;

    for(int i=1;i<=t;i++)

    {

        res=multimod(res,res,n);

        if(res==1&&last!=1&&last!=n-1) return 1;

        last=res;

    }

    if(res!=1) return 1;

    return 0;

}



int primetest(long long n)

{

    if(n<2)return 0;

    if(n==2)return 1;

    if((n&1)==0) return 0;

    long long x=n-1;

    long long t=0;

    while((x&1)==0){x>>=1;t++;}

    for(int i=0;i<20;i++)

    {

        long long a=random(n);

        if(check(a,n,x,t))

            return 0;

    }

    return 1;

}



long long pollardrho(long long n,long long c)

{

    long long x,y,d,i,k;

    i=1;k=2;

    x=random(n);

    y=x;

    while(1)

    {

        i++;

        x=(multimod(x,x,n)+c)%n;

        long long tmp=y-x>=0?y-x:x-y;

        d=gcd(tmp,n);

        if(d>1&&d<n)

            return d;

        if(y==x)

            return n;

        if(i==k)

        {

            y=x;

            k+=k;

        }

    }

}

void findfac(long long n)

{

    if(n==1)

        return;

    if(primetest(n))

    {

        fac[nf++]=n;

        return;

    }

    long long p=n;

    while(p>=n)

        p=pollardrho(n,random(n-1));

    findfac(p);

    findfac(n/p);

}

void dfs(long long x,long long y,int s,long long pre)

{

    while(fac[s]==pre&&(s<nf))

        s++;        //因子判重

    if(s==nf)

    {

        if(x+y<mk)

        {

            mk=x+y;

            ans1=x;

            ans2=y;

        }

        return;

    }

    long long i=1,j=1;

    long long a1=a,b1=b;

    while(a1%fac[s]==0)

    {

        a1/=fac[s];

    }

    while(b1%fac[s]==0)

    {

        b1/=fac[s];

    }

    i=a/a1;

    j=b/b1;

    dfs(x*i,y*j,s+1,fac[s]);

    dfs(x*j,y*i,s+1,fac[s]);

    return;

}

int main()

{



    while(scanf("%I64d %I64d",&a,&b)!=EOF)

    {

        nf=0;

        findfac(b);

        mk=9223372036854775807;

        sort(fac,fac+nf);

        dfs(1,1,0,-1);

        if(ans1>ans2)

            swap(ans1,ans2);

        printf("%I64d %I64d\n",ans1,ans2);

    }

}

 

你可能感兴趣的:(poj)