poj 2429 (分解质因子)

2014-11-24 00:36:51 · 作者: · 浏览: 1
题意:给出两个数的最大公约数g,最小公倍数lcm,求出这两个数,有多种组合的,求出和最小的一组。
思路:g=gca(a,b);a*b=lcm*g;a/g*b/g=lcm/g;gcd(a/g,b/g)=1;就是把lcm/g分解成两个互质的因子。可以用Pollard rho分解子因子,然后再将相同的因子合并,再将因子分成两部分。
#include  
#include  
#include  
#include    
#include    
#include    
#include    
typedef __int64 LL;   
LL a,b,sum;   
const int S=20;//随机算法判定次数,S越大,判错概率越小     
//***************Miller_Rabin 算法进行素数测试***************    
int cmp(void const *a,void const *b)  
{  
    if(*(LL *)a>*(LL *)b)  
        return 1;  
    else return -1;  
}  
LL mult_mod(LL a,LL x,LL n)//返回(a*x) mod n,a,x,n<2^63    
{    
    a%=n;x%=n;    
    LL ret=0;    
    while(x)    
    {    
        if(x&1){ret+=a;if(ret>=n)ret-=n;}    
        a<<=1;    
        if(a>=n)a-=n;    
        x>>=1;    
    }    
    return ret;    
}    
LL pow_mod(LL a,LL x,LL n)//返回a^x mod n    
{    
    if(x==1)return a%n;    
    int bit[70],k=0;    
    while(x)    
    {    
        bit[k++]=(x&1 1:0);    
        x>>=1;    
    }    
    LL ret=1;    
    for(--k;k>=0;k--)    
    {    
       ret=mult_mod(ret,ret,n);    
       if(bit[k])ret=mult_mod(ret,a,n);    
    }    
    return ret;    
}    
bool judge(LL a,LL n,LL x,LL t)//以a为基,n-1=x*2^t,检验n是不是合数    
{    
    LL ret=pow_mod(a,x,n),flag=ret;    
    for(LL i=1;i<=t;i++)    
    {    
        ret=mult_mod(ret,ret,n);    
        if(ret==1&&flag!=1&&flag!=n-1)return true;    
        flag=ret;    
    }    
    if(ret!=1)return true;    
    return false;    
}    
bool Miller_Rabin(LL n)    
{    
    if(n==2||n==5||n==7||n==11)return true;    
    if(n%2==0||n%5==0||n%7==0||n%11==0)return false;    
    LL x=n-1,t=0;    
    while((x&1)==0)x>>=1,t++;    
    bool flag=true;    
    if(t>=1&&(x&1)==1)    
    {    
        for(int i=1;i<=S;i++)    
        {    
            LL a=rand()%(n-1)+1;    
            if(judge(a,n,x,t)){flag=true;break;}    
            flag=false;    
        }    
    }    
    if(flag)return false;    
    else return true;    
}    
//*******pollard_rho 算法进行质因数分解*****************    
LL factor[100];//质因子    
int tot;//质因子个数    
LL gcd(LL a,LL b)    
{    
    if (a==0) return 1;    
    if (a<0) return gcd(-a,b);    
    while (b)    
    {    
        LL t=a%b; a=b; b=t;    
    }    
    return a;    
}    
LL Pollard_rho(LL x,LL c)    
{    
    LL i=1,x0=rand()%x,y=x0,k=2;    
    while (1)    
    {    
        i++;    
        x0=(mult_mod(x0,x0,x)+c)%x;    
        LL 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 find_factor(LL n) //递归进行质因数分解N    
{              
    if(Miller_Rabin(n))    
    {    
        factor[tot++] = n;return;            
    }    
    LL p=n;    
    while (p>
=n) p=Pollard_rho(p,rand() % (n-1) +1); find_factor(p); find_factor(n/p); } void dfs(int k,LL ans,LL n) { if(ans>n)return ;//ans是较小的一个,控制它小于n if(k==tot) { if(ans+sum/ansb)std::swap(a,b); printf("%I64d %I64d\n",a*g,b*g); } return 0; }