根据最大公约数和最小公倍数求原来的两个数

  题目大意,不翻译了,就是上面链接的意思。

  具体思路就是要根据数论来,设a和b的GCD(最大公约数)和LCM(最小公倍数),则a/GCD*b/GCD=LCM/GCD,我们只用枚举LCM/GCD的所有质因数就可以了,然后把相应的质因数乘以GCD即可得出答案。

  找素数很简单,用Miller_Rabin求素数的方法,可以多求几次提高正确率,原理就是用的费马定理:如果P是素数,则A^(p-1)mod P恒等于1,为了绕过Carmichael数,采用费马小定理:如果n是素数,则存在x(0<x<n),(x*x)mod n 要么是1要么是n-1,否则,x就是合数。

  另外就是要把因数分解了,这里暴力解法貌似可以,但是那种方法太笨了(也就是枚举),我们采用一个O(N^1/4)的算法Pollard_Rho快速因数分解,具体证明点我,我们把结论用上就可以了,具体将在代码中呈现。

  因数分解以后,剩下就只用DFS就可以了,注意要把所有重复的质因数先成起来,那样我们找解的时候就可以保证我们找到的解都是互质的

  参考http://www.hankcs.com/program/cpp/poj-2429-gcd-lcm-inverse.html

    http://www.cnblogs.com/chenxiwenruo/p/3567526.html

 #include <iostream>
#include <functional>
#include <algorithm>
#define MAX_N 1000 using namespace std; long long gcd(long long, long long);
bool Miller_Rabin(const long long);
long long witness(long long, long long, long long);
long long Pollard_Rho(long long,long long);
long long Multi_Mod(long long, long long);
void Find_Factors(long long, int *const, long long);
void DFS(long long, long long, int,const int);
static long long factors[MAX_N],factors_sum[MAX_N],a, b, min_sum; int main(void)
{
long long n, GCD, LCM; while (~scanf("%lld %lld", &GCD, &LCM))
{
int len = , len_factors_sum = ;
n = LCM / GCD;
if (Miller_Rabin(n))
printf("%lld %lld\n", GCD, n*GCD);
else if (LCM == GCD)
printf("%lld %lld\n", GCD, GCD);
else
{
Find_Factors(n, &len, );//120是经验值
sort(factors, factors + len);
factors_sum[] = factors[];
for (int i = ; i < len; i++)//把相同的质数全部成起来,那么当DFS的时候我们只用找这些乘积就可以了(保证a,b一定互素)
{
if (factors[i] == factors[i - ])
factors_sum[len_factors_sum] *= factors[i];
else
factors_sum[++len_factors_sum] = factors[i];
}
a = factors[]; b = n / a;
min_sum = b + a;
DFS(, , , len_factors_sum + );//找解,DFS枚举就可以了
if (a < b)
printf("%lld %lld\n", a*GCD, b*GCD);
else
printf("%lld %lld\n", b*GCD, a*GCD);
}
}
return ;
} void Find_Factors(long long n,int *const len,long long times)
{
if (n == )
return;
else if (Miller_Rabin(n))
{
factors[(*len)++] = n;//分解质因数
return;
}
else
{
long long p = n;
long long k = times;
while (p >= n)
p = Pollard_Rho(n, k--);
Find_Factors(p, len, times);
Find_Factors(n / p, len, times);
}
} bool Miller_Rabin(const long long n)
{
if (n == )
return true;
if (n == || n < )
return false;
else
{
for (int i = ; i < ; i++)//Miller_Rabin测试方法+费马定理,叠5次减少出错几率
if (!(witness((long long)rand() % (n - ) + , n - , n) == ))
return false;
return true;
}
} long long witness(long long coe, long long level, long long n)
{
long long x, y;
if (level == )
return ;//到达最后一层,开始后序遍历 x = witness(coe, level >> , n);//level以幂次递减
if (x == )
return ;//如果x出的结果是0,那么n一定是一个合数 y = (x*x) % n;
if (y == && x != && x != n - )
return ;//费马小定理,如果一个数是素数,则x*x对n的模一定是1或者是n-1,如果不是,则是合数
if (level % == )
y = (coe*y) % n;//和幂运算的道理是一样的 return y;
} long long Pollard_Rho(long long n,long long c)
{
long long x, y, k = , d;
y = x = rand() % (n - ) + ;//y和x的初始值都是定任意一个常数,然后直到找到非平常因子为止 for (int i = ;; i++)
{
x = (Multi_Mod(x, n) + c) % n;//算f(x),f(x)的定义见多项式乘法f(x)=x^2+c
d = gcd((y - x + n) % n, n);//计算|y-x|与n的最大公因数,当y==x时,返回n,说明在这个c下无法产生非平常因子
if ( < d && d < n)
return d;//如果得出d,那么d就是因数之一(不一定是质数,要继续判断)
else if (y == x)
return n;
else if (i == k)//brent判据,目的就是找到在偶数周期内找到gcd(x(k)-x(i/2))
{
y = x;
k <<= ;
}
}
return n;
} long long gcd(long long a, long long b)
{
if (b == ) return a;
return gcd(b, a%b);
} long long Multi_Mod(long long x, long long mod)//Pollard_Rho用到的多项式算法y=(x^2 + c)mod n
{
long long ans = , p = x; while (p)
{
if (p & )
ans = (ans + x) % mod;
x = (x << ) % mod;//记得取模
p >>= ;
}
return ans;
} void DFS(long long tmpa, long long tmpb, int level, const int len_factors_sum)
{
if (level == len_factors_sum)
{
if (tmpa + tmpb < min_sum)
{
a = tmpa; b = tmpb;
min_sum = tmpa + tmpb;
}
}
else
{
DFS(tmpa*factors_sum[level], tmpb, level + , len_factors_sum);
DFS(tmpa, tmpb*factors_sum[level], level + , len_factors_sum);
}
}

Mathematics:GCD & LCM Inverse(POJ 2429)的更多相关文章

  1. [POJ 2429] GCD & LCM Inverse

    GCD & LCM Inverse Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10621   Accepted: ...

  2. POJ 2429 GCD & LCM Inverse(Pollard_Rho+dfs)

    [题目链接] http://poj.org/problem?id=2429 [题目大意] 给出最大公约数和最小公倍数,满足要求的x和y,且x+y最小 [题解] 我们发现,(x/gcd)*(y/gcd) ...

  3. POJ 2429 GCD & LCM Inverse (Pollard rho整数分解+dfs枚举)

    题意:给出a和b的gcd和lcm,让你求a和b.按升序输出a和b.若有多组满足条件的a和b,那么输出a+b最小的.思路:lcm=a*b/gcd   lcm/gcd=a/gcd*b/gcd 可知a/gc ...

  4. POJ2429 GCD & LCM Inverse pollard_rho大整数分解

    Given two positive integers a and b, we can easily calculate the greatest common divisor (GCD) and t ...

  5. POJ 2429 GCD & LCM Inverse(Miller-Rabbin素性测试,Pollard rho质因子分解)

    x = lcm/gcd,假设答案为a,b,那么a*b = x且gcd(a,b) = 1,因为均值不等式所以当a越接近sqrt(x),a+b越小. x的范围是int64的,所以要用Pollard_rho ...

  6. 【poj 2429】GCD & LCM Inverse (Miller-Rabin素数测试和Pollard_Rho_因数分解)

    本题涉及的算法个人无法完全理解,在此提供两个比较好的参考. 原理 (后来又看了一下,其实这篇文章问题还是有的……有时间再搜集一下资料) 代码实现 #include <algorithm> ...

  7. poj2429 GCD & LCM Inverse

    用miller_rabin 和 pollard_rho对大数因式分解,再用dfs寻找答案即可. http://poj.org/problem?id=2429 #include <cstdio&g ...

  8. POJ2429 - GCD & LCM Inverse(Miller–Rabin+Pollard's rho)

    题目大意 给定两个数a,b的GCD和LCM,要求你求出a+b最小的a,b 题解 GCD(a,b)=G GCD(a/G,b/G)=1 LCM(a/G,b/G)=a/G*b/G=a*b/G^2=L/G 这 ...

  9. 【Pollard-rho算法】【DFS】poj2429 GCD & LCM Inverse

    题意:给你一两个数m和n,它们分别是某对数A,B的gcd和lcm,让你求出一对使得A+B最小的A,B. n/m的所有质因子中,一定有一部分是只在A中的,另一部分是只在B中的. 于是对n/m质因子分解后 ...

随机推荐

  1. UvaLive6662 The Last Ant 模拟

    UvaLive6662 PDF题目 题意:给出隧道长度L,蚂蚁数量N,各蚂蚁位置Pi.前进方向Di,都为整数(前进方向为L或R),蚂蚁速度为1cm每秒,两蚂蚁若在整数点相遇则都反向,若不在整数点相遇则 ...

  2. Nginx-tomcat-redis------负载均衡以及session共享

    测试环境 Nginx 1.10.1 tomcat 7.0.70 Redis-x64-3.2.100 说明 tomcat 8 和 redis 实现session共享 有问题. 寻找源码 发现tomcat ...

  3. JavaScript模板引擎实现数据交互

    经过1年的磨练,近期终于稍微明白到,前端是怎么做到企业要求的:数据交互. 1,ajax+json这个是必须学的,但没问题,我们可以通过这个博客来慢慢了解怎么回事? 2,可以通过JS框架和JS模板来实现 ...

  4. 【转载】Unity 优雅地管理资源,减少占用内存,优化游戏

    转自:星辰的<Unity3D占用内存太大的解决方法> 最近网友通过网站搜索Unity3D在手机及其他平台下占用内存太大. 这里写下关于Unity3D对于内存的管理与优化. Unity3D  ...

  5. iOS原生的搜索:UISearchController

    iOS8之前我们使用UISearchDisplayController做TableView的本地搜索,查看UIKit库,苹果已经使用新控件取代它. NS_CLASS_DEPRECATED_IOS(3_ ...

  6. C#之interface接口

    C#中接口与抽象类很相似,他们都无法实例化自己的对象,但是他们也有很重要的区别.Interface与Abstract class中,类不能多重继承,但是接口可以多重继承. 这段代码表明,声明接口的方法 ...

  7. Visual Studio 各种版本的快捷键总结

    下列快捷组合键可在工具和文档窗口中用于进行移动.关闭或导航. 命令名 快捷键 说明 视图.全屏 SHIFT + ALT + ENTER 在打开和关闭之间切换“全屏”模式. 视图.向后定位 CTRL + ...

  8. hibernate之persistence错误

    错误码: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityM ...

  9. Javascript添加事件的addEventListener()及attachEvent()区别分析,事件委托

    Mozilla中: addEventListener的使用方式: target.addEventListener(type, listener, useCapture); target: 文档节点.d ...

  10. Java 7 Concurrency Cookbook 翻译 第一章 线程管理之五

    九.使用线程本地变量 一个并发程序的最关键特征就是共享数据.这个特性在那些继承了 Thread 类或者 实现了 Runnable 接口的对象上显得更加重要. 如果你创建一个实现了 Runnable 接 ...