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);
    }
}

 

posted @ 2014-09-12 20:02  Lnever  阅读(401)  评论(0编辑  收藏  举报