poj 2429(因子分解 再处理一下因子即可)

因子分解很简单 直接套用模版即可。。然后之后的处理,这里一个讲解不错。。。。http://blog.sina.com.cn/s/blog_69c3f0410100uac0.html  可以参考一下的。。。

#include<iostream>
#include<ctime>
#include<algorithm>
#include<cmath>
using namespace std;
long long p,f[1000],ans;
long long f2[1000],q;
long long mod2(long long a,long long b,long long n)// a*b%n
{
    long long  exp = a%n, res = 0;
    while(b){
        if(b&1){
            res += exp;
            if(res>n) res -= n;
        }
        exp <<= 1;
        if(exp>n)  exp -= n;
        b>>=1;
    }
    return res;
}

long long mod(long long a,long long b,long long m) //(a^b)%n
{
    long long exp=a%m, res=1;
    while(b>=1){
        if(b&1)
            res=mod2(res,exp,m);
        exp = mod2(exp,exp,m);
        b>>=1;
    }
    return res;
}
//miller-rabin法测试素数
bool miller_rabin(long long n)
{
    if(n==2)return 1;
    if(n<2||!(n&1))return 0;
    long long a, u=n-1, x, y;
    int t=0;
    while(u%2==0){
        t++;
        u/=2;
    }
    srand(time(0));
    for(int i=0;i<10;i++) {
        a = rand() % (n-1) + 1;
        x = mod(a, u, n);
        for(int j=0;j<t;j++){
            y = mod2(x, x, n);
            if ( y == 1 && x != 1 && x != n-1 )
                return false;
            x = y;
        }
        if( y!=1) return false;
    }
    return true;
}
// 因子分解
long long gcd(long long a,long long b){
    long long c;
    while(b){
        c=b; b=a%b; a=c;
    }
    return a;
}
long long pollard_rho(long long n,long long k){
    srand(time(0));
    long long x=rand()%(n-1)+1;
    long long i=1,t=2,y=x,d;
    while(1){
        i++;
        x=(mod2(x,x,n)+k)%n;
        d=gcd(y-x,n);
        if(d>1 && d<n) return d;
        if(x==y) return n;
        if(t==i) y=x,t<<=1;
    }
}
void get_factor(long long n,long long k){
    if(miller_rabin(n)){
        f[p++]=n;
       return ;
    }
    long long h=n;
    while(h>=n)
        h=pollard_rho(h,k--);
    get_factor(h,k);
    get_factor(n/h,k);
}
void dfs(long long i,long long x,long long k){
    if(i>q) return ;
    if(x>ans && x<=k) ans=x;
    dfs(i+1,x,k);
    x*=f2[i];
    if(x>ans && x<=k) ans=x;
    dfs(i+1,x,k);
}
int main(int argc, char** argv) {
    long long m,n,k;
    while(scanf("%lld%lld",&m,&n)!=-1){
        if(m==n){
            printf("%lld %lld\n",m,n); continue;
        }
        k=n/m; p=0; q=0; ans=1;
        get_factor(k,180);
        sort(f,f+p);
        f2[0]=f[0];
        for(int i=0;i<p-1;i++)
            if(f[i]==f[i+1]) f2[q]*=f[i+1];
            else{
                q++; f2[q]=f[i+1];
            }
        long long tmp=(long long)sqrt(k*1.0);
        dfs(0,1,tmp);
        printf("%lld %lld\n",m*ans,k/ans*m);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值