您的位置:首页 > 其它

poj 2429 GCD & LCM Inverse

2013-08-12 16:41 369 查看
题目:poj 2429 GCD & LCM Inverse

思路:对于输入的g,l,要找到一组(a,b)满足g=gcd(a,b),l=lcm(a,b)且min(a+b),那么对tmp=l/g,我们需要对tmp进行质因式分解,将分解的部分乘上g,得到a,b,假设tmp中分给a的部分是i,那么a=g*i,b=g*(tmp/i) 也就是 l/i ,那么对于a+b=g*i+g*(tmp/i)=g*(i+tmp*i),也就是要找到一个最接近sqrt(tmp)的数 i (是tmp的约数) (分配的过程必须把该质数的所有幂都给出去,不然会改变gcd(a,b)的值)

这题的时限对java不是很严,写个while就可以水过,具体见代码

import java.util.*;
import java.math.*;
public class Main{
	static long gcd(long a,long b){
		if(b==0)
			return a;
		return gcd(b,a%b);
	}
	static long lcm(long a,long b){
		return a/gcd(a,b)*b;
	}
	public static void main(String args[]){
		long g,l,tmp;
		Scanner cin=new Scanner(System.in);
		while(cin.hasNext()){
			g=cin.nextLong();
			l=cin.nextLong();
			tmp=l/g;
			long cnt=(long)Math.sqrt(tmp+0.0);
			while(tmp%cnt!=0 || gcd(cnt,tmp/cnt)!=1)
				cnt--;
			System.out.println(g*cnt+" "+l/cnt);
		}
	}
}


既然用C++会超时的话,对于一个较大数的分解,用pollard大数分解模板,然后dfs

将tmp质因数分解之后,tmp=p1^x1 * p2^x2 * ... pn^xn 由于对一个质因子必须把所有幂给出去,所以我就用vector将这些存起来了。

然后对于vector里面的元素,dfs一下求最接近sqrt(tmp)的值,就ok了

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <cstdlib>
#include <vector>
using namespace std;
#define Times 10
map<long long,int>m;
vector<long long>v;
long long cnt,answer;
long long g,l;
long long random(long long n)
{
    return ((double)rand()/RAND_MAX*n+0.5);
}
long long multi(long long a,long long b,long long mod)
{
    long long ans=0;
    while(b)
    {
        if(b&1)
        {
            b--;
            ans=(ans+a)%mod;
        }
        else
        {
            b/=2;
            a=(2*a)%mod;
        }
    }
    return ans;
}
long long Pow(long long a,long long b,long long mod)
{
    long long ans=1;
    while(b)
    {
        if(b&1)
        {
            b--;
            ans=multi(ans,a,mod);
        }
        else
        {
            b/=2;
            a=multi(a,a,mod);
        }
    }
    return ans;
}
long long Pow(long long a,long long b)
{
    long long ans=1;
    while(b)
    {
        if(b&1)
        {
            b--;
            ans=ans*a;
        }
        else
        {
            b/=2;
            a*=a;
        }
    }
    return ans;
}
bool witness(long long a,long long n)
{
    long long d=n-1;
    while(!(d&1))
        d>>=1;
    long long t=Pow(a,d,n);
    while(d!=n-1 && t!=1 && t!=n-1)
    {
        t=multi(t,t,n);
        d<<=1;
    }
    return t==n-1 || d&1;
}
bool miller_rabin(long long n)
{
    if(n==2)
        return true;
    if(n<2||!(n&1))
        return false;
    for(int i=1;i<=Times;i++)
    {
        long long a=random(n-2)+1;
        if(!witness(a,n))
            return false;
    }
    return true;
}
long long gcd(long long a,long long b)
{
    if(b==0)
        return a;
    return gcd(b,a%b);
}
long long pollard_rho(long long n,int c)
{
    long long x,y,d,i=1,k=2;
    x=random(n-2)+1;
    y=x;
    while(1)
    {
        i++;
        x=(multi(x,x,n)+c)%n;
        d=gcd(y-x,n);
        if(1<d&&d<n)
            return d;
        if(y==x)
            return n;
        if(i==k)
        {
            y=x;
            k<<=1;
        }
    }
}
void find(long long n,int c)
{
    if(n==1)
        return ;
    if(miller_rabin(n))
    {
        m
++;
        return ;
    }
    long long p=n;
    while(p>=n)
        p=pollard_rho(p,c--);
    find(p,c);
    find(n/p,c);
}
void dfs(int index,long long now)
{
    if(index==v.size())
        return ;
    if(now>answer&&now<=cnt) answer=now;
    dfs(index+1,now);
    now*=v[index];
    if(now>answer&&now<=cnt) answer=now;
    dfs(index+1,now);
}
int main()
{
    while(scanf("%I64d%I64d",&g,&l)!=EOF)
    {
        m.clear();
        v.clear();
        long long tmp=l/g;
        cnt=(long long)sqrt(tmp);
        find(tmp,12312);
        map<long long,int>::iterator it=m.begin();
        for(;it!=m.end();it++)
            v.push_back(Pow(it->first,it->second));
        answer=1;
        dfs(0,1);
        g*=answer;
        l/=answer;
        printf("%I64d %I64d\n",g,l);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: