POJ2429 GCD & LCM Inverse

来源:互联网 发布:网络电视要不要机顶盒 编辑:程序博客网 时间:2024/05/23 10:12

要点:大数质因子分解(Pollard_rho就可以解决)

题目链接:http://poj.org/problem?id=2429

代码好长呀!抓狂

#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<stdlib.h>#include<math.h>#include<algorithm>using namespace std;#define ll long long#define nn 110#define S 20ll pr[nn],f[nn];int tol,k;ll ans;ll mult_mod(ll a,ll b,ll c)//(a*b)%c{    a%=c;    b%=c;    ll ret=0;    while(b)    {        if(b&1)        {            ret+=a;            ret%=c;        }        a<<=1;        if(a>=c)            a%=c;        b>>=1;    }    return ret;}ll pow_mod(ll x,ll n,ll mod)//取模x^n%c{    if(n==1)        return x%mod;    x%=mod;    ll tmp=x;    ll ret=1;    while(n)    {        if(n&1)            ret=mult_mod(ret,tmp,mod);        tmp=mult_mod(tmp,tmp,mod);        n>>=1;    }    return ret;}bool check(ll a,ll n,ll x,ll t){    ll ret=pow_mod(a,x,n);    ll last=ret;    for(int i=1;i<=t;i++)    {        ret=mult_mod(ret,ret,n);        if(ret==1&& last!=n-1 && last!=1)            return true;        last=ret;    }    if(ret!=1) return true;    return false;}bool miller_rabin(ll n)//判断n是否为素数{    if(n<2) return false;    if(n==2) return true;    if((n&1)==0) return false;    ll x=n-1;    ll t=0;    while((x&1)==0)    {        x>>=1;        t++;    }    for(int i=0;i<S;i++)    {        ll a=rand()%(n-1)+1;        if(check(a,n,x,t))            return false;    }    return true;}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,k=2;    ll x0=rand()%x;    ll y=x0;    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 findfac(ll n){    if(miller_rabin(n))    {        pr[tol++]=n;        return;    }    ll p=n;    while(p>=n)        p=pollard_rho(p,rand()%(n-1)+1);    findfac(p);    findfac(n/p);}void findx(ll i,ll x,ll q){    if(i==k) return ;    if(x>ans && x<=q)        ans=x;    findx(i+1,x,q);    x*=f[i];    if(x>ans&& x<=q)        ans=x;    findx(i+1,x,q);}int main(){    ll a,b,m;    while(~scanf("%lld%lld",&a,&b))    {        if(a==b)        {            printf("%lld %lld\n",a,b);            continue;        }        ll n=b/a;        tol=0;        findfac(n);        sort(pr,pr+tol);        k=1;        f[0]=1;        for(int i=1;i<tol;i++)        {            if(pr[i]==pr[i-1])                f[k-1]++;            else            {                pr[k++]=pr[i];                f[k-1]=1;            }        }//        for(int i=0;i<k;i++)//            printf("%lld %lld\n",pr[i],f[i]);//        printf("\n");        ll j,m;        for(int i=0;i<k;i++){//将相同素因子作为一个整体处理            for(j=1,m=pr[i];j<f[i];j++)                m*=pr[i];            f[i]=m;        }//        for(int i=0;i<k;i++)//            printf("%lld %lld\n",pr[i],f[i]);//        printf("\n");        ll q=(ll)sqrt(n*1.0);        ans=1;        findx(0,1,q);//        printf("ans==%lld\n",ans);        printf("%lld %lld\n",ans*a,n/ans*a);    }    return 0;}


0 0
原创粉丝点击