POJ2429 GCDLCM Inverse(整数分解,由GCD+LCM求a,b)
POJ2429 GCD&LCM Inverse(整数分解,由GCD+LCM求a,b)
题目: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最小的,然后就分析完毕。
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <algorithm>
- #include <iostream>
- using namespace std;
- #define LL unsigned long long
- const int Times=10;
- const LL INF=(LL)1<<61;
- const int N=550;
- LL n,m,ct,cnt,mini,mina,minb,ans;
- LL fac[N],num[N];
- LL gcd(LL a,LL b)
- {
- return b? gcd(b,a%b):a;
- }
- LL multi(LL a,LL b,LL m)
- {
- LL ans=0;
- while(b)
- {
- if(b&1)
- {
- ans=(ans+a)%m;
- b--;
- }
- b>>=1;
- a=(a+a)%m;
- }
- return ans;
- }
- LL quick_mod(LL a,LL b,LL m)
- {
- LL ans=1;
- a%=m;
- while(b)
- {
- if(b&1)
- {
- ans=multi(ans,a,m);
- b--;
- }
- b>>=1;
- a=multi(a,a,m);
- }
- return ans;
- }
- bool Miller_Rabin(LL n)
- {
- if(n==2) return true;
- if(n<2||!(n&1)) return false;
- LL a,m=n-1,x,y;
- int k=0;
- while((m&1)==0)
- {
- k++;
- m>>=1;
- }
- for(int i=0;i<Times;i++)
- {
- a=rand()%(n-1)+1;
- x=quick_mod(a,m,n);
- for(int j=0;j<k;j++)
- {
- y=multi(x,x,n);
- if(y==1&&x!=1&&x!=n-1) return false;
- x=y;
- }
- if(y!=1) return false;
- }
- return true;
- }
- LL Pollard_rho(LL n,LL c)
- {
- LL x,y,d,i=1,k=2;
- y=x=rand()%(n-1)+1;
- while(true)
- {
- i++;
- x=(multi(x,x,n)+c)%n;
- d=gcd((y-x+n)%n,n);
- if(1<d&&d<n) return d;
- if(y==x) return n;
- if(i==k)
- {
- y=x;
- k<<=1;
- }
- }
- }
- void find(LL n,int c)
- {
- if(n==1) return;
- if(Miller_Rabin(n))
- {
- fac[ct++]=n;
- return ;
- }
- LL p=n;
- LL k=c;
- while(p>=n) p=Pollard_rho(p,c--);
- find(p,k);
- find(n/p,k);
- }
- void dfs(LL c,LL value)
- {
- LL s=1,a,b;
- if(c==cnt)
- {
- a=value;
- b=ans/a;
- if(gcd(a,b)==1)
- {
- a*=n;
- b*=n;
- if(a+b<mini)
- {
- mini=a+b;
- mina=a;
- minb=b;
- }
- }
- return ;
- }
- for(LL i=0;i<=num[c];i++)
- {
- if(s*value>mini) return;
- dfs(c+1,s*value);
- s*=fac[c];
- }
- }
- int main()
- {
- while(~scanf("%llu%llu",&n,&m))
- {
- if(n==m)
- {
- printf("%llu %llu\n",n,m);
- continue;
- }
- mini=INF;
- ct=cnt=0;
- ans=m/n;
- find(ans,120);
- sort(fac,fac+ct);
- num[0]=1;
- int k=1;
- for(LL i=1;i<ct;i++)
- {
- if(fac[i]==fac[i-1])
- ++num[k-1];
- else
- {
- num[k]=1;
- fac[k++]=fac[i];
- }
- }
- cnt=k;
- dfs(0,1);
- if(mina>minb) swap(mina,minb);
- printf("%llu %llu\n",mina,minb);
- }
- return 0;
- }
POJ2429 GCDLCM Inverse(整数分解,由GCD+LCM求a,b)相关推荐
- 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 ...
- 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 ...
- 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= ...
- 已知gcd和lcm求a+b最小和?------数论
题意 给出2个数a,b的 gcd(最大公约数n) 和 lcm(最小公倍数m),求所有符合条件的a,b中, 的最小 值. 思路 暴力枚举.根据 gcd(a,b)lcm(a,b)=ab 我们可以得到 ab ...
- hdu-3071 Gcd Lcm game---质因数分解+状态压缩+线段树
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3071 题目大意: 给定一个长度为n的序列m次操作,操作的种类一共有三种 查询 L :查询一个区间的所 ...
- c语言判断素数squ,poj1811——Prime Test//素数判断+整数分解因子
题意:给定N,如果N为素数,输出"Prime",否则输出其最小因子. 思路:用miller_rabin判断素数,pollardRho用于整数因子的分解.整数因子分解还有一个更快的算 ...
- 数论 —— 整数分解
[概述] 整数分解目前仍是世界级难题,是非常重要的研究方向,其有很多种算法,性能上各有差异,本文仅介绍试除法.Fermat 算法.Pollard Rho 算法. [试除法] 试除法也叫穷举法,是整数分 ...
- VJ 1033 整数分解(版本2)
描述 整数分解(版本2) 一个正整数可以分解成若干个自然数之和.请你编一个程序,对于给出的一个正整数n(1<=n<=1500),求出满足要求的分解方案,并使这些自然数的乘积m达到最大. 例 ...
- UVa 11388 - GCD LCM
题目大意:给出两个数的最大公约数G和最小公倍数L,求出这两个数. 根据a*b = GCD * LCM,然后枚举判断就好了. 1 #include <cstdio> 2 typedef un ...
最新文章
- 【干货】NLP中对困惑度感到困惑?
- 用户视角看百度移动:从流量集散地到流量目的地
- 页面放在哪_seo页面怎么优化?seo页面优化有哪些方法?
- android dropbox anr分析,Android如何分析排查ANR
- 数易云备开启虚拟机备份新时代
- 小程序入门学习18--springboot环境配置02
- 使用zend studio配置Xdebug调试PHP教程
- 基于Java保险员工管理系统的设计与实现
- C语言实现一个简单的矩阵运算器
- 【Adobe Illustrator 教程】4. 认识渐变工具
- 雷军博客分享-日本的电饭煲到底好在哪?
- linux c语言 写文件,linux c通过文件描述符以及write和read方法对文件进行读写
- 使用Cytoscape画PPI网络图
- 从虚拟机到容器,详谈各种服务虚拟化技术及其应用场景
- MAAS+JUJU+CONJURE-UP全自动部署OPENSTACK
- 006.尚学堂阶段1_简单错误如何处理_守破离学习法_程序员修炼手册
- NOIP 2003年普及组 3. 栈
- Revit如何将明细表导出为DWG格式【批量导出图纸】
- 图解 DataX 核心设计原理
- 清华大学计算机系九推,人工智能琴棋诗画样样精通,就问你怕不怕 | 清华大学计算机系智能体晚会...