GCD & LCM Inverse
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 16206   Accepted: 3008

Description

Given two positive integers a and b, we can easily calculate the greatest common divisor (GCD) and the least common multiple (LCM) of a and b. But what about the inverse? That is: given GCD and LCM, finding a and b.

Input

The input contains multiple test cases, each of which contains two positive integers, the GCD and the LCM. You can assume that these two numbers are both less than 2^63.

Output

For each test case, output a and b in ascending order. If there are multiple solutions, output the pair with smallest a + b.

Sample Input

3 60

Sample Output

12 15

Source

题意:
给出gcd和lcm求和最小的两个数a,b
代码:
//a*b=gcd*lcm,x=a/gcd,y=b/gcd,s=lcm/gcd => x*y=s;
//想要a+b小 => x*gcd+y*gcd小 => x+y小,x和y越接近sqrt(S)时x+y越小(对勾函数)
//所以求出s的素因子然后搞一搞就行了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<algorithm>
using namespace std;
typedef long long ll;
const int S=;//随机算法判定次数,S越大判错概率越小
//计算(a*b)%c;a,b,c<2^63
ll mult_mod(ll a,ll b,ll c){
a%=c;
b%=c;
ll ret=;
while(b){
if(b&){
ret+=a;
ret%=c;
}
a<<=;
if(a>=c) a%=c;
b>>=;
}
return ret;
}
//计算(x^n)%c
ll pow_mod(ll x,ll n,ll c){
if(n==) return x%c;
x%=c;
ll tmp=x;
ll ret=;
while(n){
if(n&) ret=mult_mod(ret,tmp,c);
tmp=mult_mod(tmp,tmp,c);
n>>=;
}
return ret;
}
//以a为基,n-1=x*2^t a^(n-1)=1(mod n) 验证n是不是合数
//一定是合数返回true,不一定返回false
bool check(ll a,ll n,ll x,ll t){
ll ret=pow_mod(a,x,n);
ll last=ret;
for(int i=;i<=t;i++){
ret=mult_mod(ret,ret,n);
if(ret==&&last!=&&last!=n-) return true;
last=ret;
}
if(ret!=) return true;
return false;
}
// Miller_Rabin()算法素数判定
//是素数返回true.(可能是伪素数,但概率极小)
//合数返回false;
bool Miller_Rabin(ll n){
if(n<) return false;
if(n==) return true;
if((n&)==) return false;
ll x=n-;
ll t=;
while((x&)==){
x>>=;
t++;
}
for(int i=;i<S;i++){
ll a=rand()%(n-)+;
if(check(a,n,x,t)) return false;
}
return true;
}
ll gcd(ll a,ll b){
if(a==) return ;
if(a<) return gcd(-a,b);
while(b){
ll t=a%b;
a=b;
b=t;
}
return a;
}
//Pollard_rho质因数分解算法
ll factor[];//质因数分解结果(无序的)
int tot;//质因数的个数,数组下标从0开始
ll Pollard_rho(ll x,ll c){
ll i=,k=;
ll x0=rand()%x;
ll y=x0;
while(){
i++;
x0=(mult_mod(x0,x0,x)+c)%x;
ll d=gcd(y-x0,x);
if(d!=&&d!=x) return d;
if(y==x0) return x;
if(i==k){
y=x0;
k+=k;
}
}
}
//对n进行素因子分解
void findfac(ll n){
if(Miller_Rabin(n)){//素数
factor[tot++]=n;
return;
}
ll p=n;
while(p>=n)
p=Pollard_rho(p,rand()%(n-)+);
findfac(p);
findfac(n/p);
}
ll ans,fa[];
int nu;
void dfs(int st,ll x,ll maxx)
{
if(st>nu){
if(x<=maxx&&x>ans)
ans=x;
return;
}
dfs(st+,x,maxx);
dfs(st+,x*fa[st],maxx);
}
int main()
{
//srand(time(NULL));
ll a,b;
while(scanf("%lld%lld",&a,&b)==){
if(a==b){
printf("%lld %lld\n",a,b);
continue;
}
tot=nu=;
ll s=b/a;
findfac(s);
sort(factor,factor+tot);
fa[]=factor[];
for(int i=;i<tot;i++){//合并相同的素因子
if(factor[i]==factor[i-]) fa[nu]*=factor[i];
else
fa[++nu]=factor[i];
}
ll x=(ll)sqrt(s*1.0);
ans=;
dfs(,,x);
printf("%lld %lld\n",ans*a,s/ans*a);
}
return ;
}

POJ 2429 long long 质因数分解的更多相关文章

  1. poj 3421 X-factor Chains——质因数分解

    题目:http://poj.org/problem?id=3421 记忆化搜索竟然水过去了.仔细一想时间可能有点不对,但还是水过去了. #include<iostream> #includ ...

  2. POJ 2167 Irrelevant Elements 质因数分解

    Irrelevant Elements Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 2231   Accepted: 55 ...

  3. POJ 1845 Sumdiv#质因数分解+二分

    题目链接:http://poj.org/problem?id=1845 关于质因数分解,模板见:http://www.cnblogs.com/atmacmer/p/5285810.html 二分法思想 ...

  4. 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 ...

  5. poj 2429 Pollard_rho大数分解

    先对lcm/gcd进行分解,问题转变为从因子中选出一些数相乘,剩下的数也相乘,要求和最小. 这里能够直接搜索,注意一个问题,因为同样因子不能分配给两边(会改变gcd)所以能够将同样因子合并,这种话,搜 ...

  6. Poj 1401 Factorial(计算N!尾数0的个数——质因数分解)

    一.Description The most important part of a GSM network is so called Base Transceiver Station (BTS). ...

  7. algorithm@ 大素数判定和大整数质因数分解

    #include<stdio.h> #include<string.h> #include<stdlib.h> #include<time.h> #in ...

  8. 求n!质因数分解之后素数a的个数

    n!质因数分解后P的个数=n/p+n/(p*p)+n/(p*p*p)+......直到n<p*p*p*...*p //主要代码,就这么点东西,数学真是厉害啊!幸亏我早早的就退了数学2333 do ...

  9. AC日记——质因数分解 1.5 43

    43:质因数分解 总时间限制:  1000ms 内存限制:  65536kB 描述 已知正整数 n 是两个不同的质数的乘积,试求出较大的那个质数. 输入 输入只有一行,包含一个正整数 n. 对于60% ...

随机推荐

  1. hdu刷题1

    1002  大数加法 #include<iostream> #include<cstring> using namespace std; int main() { ],b[]; ...

  2. vs_code 快捷键

    一般的Ctrl+Shift+P,F1显示命令面板按Ctrl+P快速打开,到文件.Ctrl + Shift + N新窗口/实例Ctrl + Shift + W /关闭窗口实例Ctrl +.用户设置Ctr ...

  3. Windows下PHP安全环境的搭建

    笔者一直在Windows环境下搭建PHP的运行环境,大大小小的运行环境用过不少,从开始的WAMP到后来的XAMPP以及PHPnow.WAMP和XAMPP都是继承mysql apache以及PHP库的运 ...

  4. LeetCode 142——环形链表 II

    1. 题目 2. 解答 2.1 方法 1 定义快慢两个指针,慢指针每次前进一步,快指针每次前进两步,若链表有环,则快慢指针一定会相遇. 当快慢指针相遇时,我们让慢指针指向头节点,快指针不变,然后每次快 ...

  5. lsscsi命令详解

    基础命令学习目录首页 lsscsi包默认是不安装的.lsscsi包安装完之后,lsscsi命令就可以使用了.lsscsi命令(lsscsi -t -L)能很方便的看出哪些是固态硬盘(SSD),哪些是S ...

  6. window.open()与window.showModalDialog区别

    window.open()与window.showModalDialog区别 弹出窗口两种方式:    1.window.showModalDialog:      var feature = &qu ...

  7. 五:ResourceManager High Availability RM 高可用

    RM有单点失败的风险,但是可以做HA.  RMs HA通过master/standby这种结构实现,一个master是active的,其它standby是inactive的.可能通过命令行切换主备节点 ...

  8. [leetcode-667-Beautiful Arrangement II]

    Given two integers n and k, you need to construct a list which contains n different positive integer ...

  9. POJ 1739 Tony's Tour(插头DP)

    Description A square township has been divided up into n*m(n rows and m columns) square plots (1< ...

  10. tomcat端口号修改

    修改Tomcat的端口号: 在默认情况下,tomcat的端口是8080,如果出现8080端口号冲突,用如下方法可以修改Tomcat的端口号: 首先: 在Tomcat的根(安装)目录下,有一个conf文 ...