POJ2429 GCD&LCM Inverse(整数分解,由GCD+LCM求a,b)

分类: 数论 2013-02-12 22:00  180人阅读  评论(1)  收藏  举报

题目:GCD & LCM Inverse

 

题意:给你两个数G和L分别是a,b的最大公约数和最小公倍数,求a,b。(有多组a,b的情况下取a+b最小的)

分析:由于 G和L分别是a,b的最大公约数和最小公倍数,那么G一定整除L,否则就没有解了。

进一步可以知道L/G的素因子分解式中,同一项不会同时出现在a,b中,因为相同的在G中已经除掉了.

那么有:,所以我们现在只需要枚举L/G的约数,枚举的一个x在a中,那么另一个(L/G)/x就是在b中,但是我们知道

,,所以思路就是对L/G先分解,因为这个数很大,所以就用Pollard-rho分解法吧,分解之后,利用

dfs找因子,然后每找到一个就判断一次来记录a+b最小的,然后就分析完毕。

[cpp]  view plain copy
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <algorithm>
  5. #include <iostream>
  6. using namespace std;
  7. #define LL unsigned long long
  8. const int Times=10;
  9. const LL INF=(LL)1<<61;
  10. const int N=550;
  11. LL n,m,ct,cnt,mini,mina,minb,ans;
  12. LL fac[N],num[N];
  13. LL gcd(LL a,LL b)
  14. {
  15. return b? gcd(b,a%b):a;
  16. }
  17. LL multi(LL a,LL b,LL m)
  18. {
  19. LL ans=0;
  20. while(b)
  21. {
  22. if(b&1)
  23. {
  24. ans=(ans+a)%m;
  25. b--;
  26. }
  27. b>>=1;
  28. a=(a+a)%m;
  29. }
  30. return ans;
  31. }
  32. LL quick_mod(LL a,LL b,LL m)
  33. {
  34. LL ans=1;
  35. a%=m;
  36. while(b)
  37. {
  38. if(b&1)
  39. {
  40. ans=multi(ans,a,m);
  41. b--;
  42. }
  43. b>>=1;
  44. a=multi(a,a,m);
  45. }
  46. return ans;
  47. }
  48. bool Miller_Rabin(LL n)
  49. {
  50. if(n==2) return true;
  51. if(n<2||!(n&1)) return false;
  52. LL a,m=n-1,x,y;
  53. int k=0;
  54. while((m&1)==0)
  55. {
  56. k++;
  57. m>>=1;
  58. }
  59. for(int i=0;i<Times;i++)
  60. {
  61. a=rand()%(n-1)+1;
  62. x=quick_mod(a,m,n);
  63. for(int j=0;j<k;j++)
  64. {
  65. y=multi(x,x,n);
  66. if(y==1&&x!=1&&x!=n-1) return false;
  67. x=y;
  68. }
  69. if(y!=1) return false;
  70. }
  71. return true;
  72. }
  73. LL Pollard_rho(LL n,LL c)
  74. {
  75. LL x,y,d,i=1,k=2;
  76. y=x=rand()%(n-1)+1;
  77. while(true)
  78. {
  79. i++;
  80. x=(multi(x,x,n)+c)%n;
  81. d=gcd((y-x+n)%n,n);
  82. if(1<d&&d<n) return d;
  83. if(y==x) return n;
  84. if(i==k)
  85. {
  86. y=x;
  87. k<<=1;
  88. }
  89. }
  90. }
  91. void find(LL n,int c)
  92. {
  93. if(n==1) return;
  94. if(Miller_Rabin(n))
  95. {
  96. fac[ct++]=n;
  97. return ;
  98. }
  99. LL p=n;
  100. LL k=c;
  101. while(p>=n) p=Pollard_rho(p,c--);
  102. find(p,k);
  103. find(n/p,k);
  104. }
  105. void dfs(LL c,LL value)
  106. {
  107. LL s=1,a,b;
  108. if(c==cnt)
  109. {
  110. a=value;
  111. b=ans/a;
  112. if(gcd(a,b)==1)
  113. {
  114. a*=n;
  115. b*=n;
  116. if(a+b<mini)
  117. {
  118. mini=a+b;
  119. mina=a;
  120. minb=b;
  121. }
  122. }
  123. return ;
  124. }
  125. for(LL i=0;i<=num[c];i++)
  126. {
  127. if(s*value>mini) return;
  128. dfs(c+1,s*value);
  129. s*=fac[c];
  130. }
  131. }
  132. int main()
  133. {
  134. while(~scanf("%llu%llu",&n,&m))
  135. {
  136. if(n==m)
  137. {
  138. printf("%llu %llu\n",n,m);
  139. continue;
  140. }
  141. mini=INF;
  142. ct=cnt=0;
  143. ans=m/n;
  144. find(ans,120);
  145. sort(fac,fac+ct);
  146. num[0]=1;
  147. int k=1;
  148. for(LL i=1;i<ct;i++)
  149. {
  150. if(fac[i]==fac[i-1])
  151. ++num[k-1];
  152. else
  153. {
  154. num[k]=1;
  155. fac[k++]=fac[i];
  156. }
  157. }
  158. cnt=k;
  159. dfs(0,1);
  160. if(mina>minb) swap(mina,minb);
  161. printf("%llu %llu\n",mina,minb);
  162. }
  163. return 0;
  164. }

POJ2429 GCDLCM Inverse(整数分解,由GCD+LCM求a,b)相关推荐

  1. POJ 2429 GCD LCM Inverse (整数分解,由gcd+lcm求a,b)

    题意:给你两个数a,b的最大公约数和最小公倍数,求a,b.(有多组a,b的情况下取a+b最小的) 题解:令 c = a * b / gcd(a,b),对 c 因式分解 假如c = p1^k1 * p2 ...

  2. GCD and LCM Aizu - 0005(辗转相除)+GCD LCM Inverse POJ - 2429(java或【Miller Rabin素数測试】+【Pollar Rho整数分解】)

    题目:GCD and LCM Aizu - 0005 Write a program which computes the greatest common divisor (GCD) and the ...

  3. POJ 2429 GCD LCM Inverse

    设答案为ans1,ans2 ans1=a1*gcd,ans2=a2*gcd,a1,a2互质 gcd*a1*b1=lcm,gcd*a2*b2=lcm a1*b1=lcm=(ans1*ans2)/gcd= ...

  4. 已知gcd和lcm求a+b最小和?------数论

    题意 给出2个数a,b的 gcd(最大公约数n) 和 lcm(最小公倍数m),求所有符合条件的a,b中, 的最小 值. 思路 暴力枚举.根据 gcd(a,b)lcm(a,b)=ab 我们可以得到 ab ...

  5. hdu-3071 Gcd Lcm game---质因数分解+状态压缩+线段树

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3071 题目大意: 给定一个长度为n的序列m次操作,操作的种类一共有三种 查询 L :查询一个区间的所 ...

  6. c语言判断素数squ,poj1811——Prime Test//素数判断+整数分解因子

    题意:给定N,如果N为素数,输出"Prime",否则输出其最小因子. 思路:用miller_rabin判断素数,pollardRho用于整数因子的分解.整数因子分解还有一个更快的算 ...

  7. 数论 —— 整数分解

    [概述] 整数分解目前仍是世界级难题,是非常重要的研究方向,其有很多种算法,性能上各有差异,本文仅介绍试除法.Fermat 算法.Pollard Rho 算法. [试除法] 试除法也叫穷举法,是整数分 ...

  8. VJ 1033 整数分解(版本2)

    描述 整数分解(版本2) 一个正整数可以分解成若干个自然数之和.请你编一个程序,对于给出的一个正整数n(1<=n<=1500),求出满足要求的分解方案,并使这些自然数的乘积m达到最大. 例 ...

  9. UVa 11388 - GCD LCM

    题目大意:给出两个数的最大公约数G和最小公倍数L,求出这两个数. 根据a*b = GCD * LCM,然后枚举判断就好了. 1 #include <cstdio> 2 typedef un ...

最新文章

  1. 【干货】NLP中对困惑度感到困惑?
  2. 用户视角看百度移动:从流量集散地到流量目的地
  3. 页面放在哪_seo页面怎么优化?seo页面优化有哪些方法?
  4. android dropbox anr分析,Android如何分析排查ANR
  5. 数易云备开启虚拟机备份新时代
  6. 小程序入门学习18--springboot环境配置02
  7. 使用zend studio配置Xdebug调试PHP教程
  8. 基于Java保险员工管理系统的设计与实现
  9. C语言实现一个简单的矩阵运算器
  10. 【Adobe Illustrator 教程】4. 认识渐变工具
  11. 雷军博客分享-日本的电饭煲到底好在哪?
  12. linux c语言 写文件,linux c通过文件描述符以及write和read方法对文件进行读写
  13. 使用Cytoscape画PPI网络图
  14. 从虚拟机到容器,详谈各种服务虚拟化技术及其应用场景
  15. MAAS+JUJU+CONJURE-UP全自动部署OPENSTACK
  16. 006.尚学堂阶段1_简单错误如何处理_守破离学习法_程序员修炼手册
  17. NOIP 2003年普及组 3. 栈
  18. Revit如何将明细表导出为DWG格式【批量导出图纸】
  19. 图解 DataX 核心设计原理
  20. 清华大学计算机系九推,人工智能琴棋诗画样样精通,就问你怕不怕 | 清华大学计算机系智能体晚会...

热门文章

  1. 树莓派pico mpu6050 一阶互补滤波四元数法 解算姿态角
  2. Linux Signal信号表
  3. Python爬虫:url中带字典列表参数的编码转换
  4. EXCEL两列数据不同值比较标记
  5. 用Docker部署SSM项目
  6. 内网渗透----netcat工具使用
  7. [附源码]计算机毕业设计Python+uniapp智慧校园APP的设计与实现55q4l(程序+lw+APP+远程部署)
  8. 泛微ecology 修改在线预览附件 大小限制
  9. 程序设计与c语言笔记(一)
  10. 串口编程 - 串口简介