POJ-2429 GCD & LCM Inverse---给出gcd和lcm求原来两个数
题目链接:
https://cn.vjudge.net/problem/POJ-2429
题目大意:
给出两个数的gcd和lcm,求原来的这两个数(限定两数之和最小)。
解题思路:
首先,知道gcd和lcm求原来的两个数,需要分解lcm / gcd 。将其分解为互质的两个数。
首先将lcm/gcd质因数分解,要分解出沪互质两个数字,那么这两个数字的gcd=1,也就是没有公共的质因子,所以可以直接枚举这两个数字的质因子,如果一个数要取这个质因子,就把它的指数全部取掉。
质因数分解用大数因式分解来做。
分成两个互质的数字可以用二进制枚举子集,1表示取这个质因数,0表示不取,最终求出最小的和的两个数。
#include<iostream>
#include<ctime>
#include<algorithm>
#include<map>
#define INF 1000000000000000009
using namespace std;
typedef long long ll;
map<ll, int>m;
const int mod = ;
const int times = ;//测试50次
ll mul(ll a, ll b, ll m)
//求a*b%m
{
ll ans = ;
a %= m;
while(b)
{
if(b & )ans = (ans + a) % m;
b /= ;
a = (a + a) % m;
}
return ans;
}
ll pow(ll a, ll b, ll m)
//a^b % m
{
ll ans = ;
a %= m;
while(b)
{
if(b & )ans = mul(a, ans, m);
b /= ;
a = mul(a, a, m);
}
ans %= m;
return ans;
}
bool Miller_Rabin(ll n, int repeat)//n是测试的大数,repeat是测试重复次数
{
if(n == || n == )return true;//特判
if(n % == || n == )return false;//偶数和1 //将n-1分解成2^s*d
ll d = n - ;
int s = ;
while(!(d & )) ++s, d >>= ;
//srand((unsigned)time(NULL));在最开始调用即可
for(int i = ; i < repeat; i++)//重复repeat次
{
ll a = rand() % (n - ) + ;//取一个随机数,[2,n-1)
ll x = pow(a, d, n);
ll y = ;
for(int j = ; j < s; j++)
{
y = mul(x, x, n);
if(y == && x != && x != (n - ))return false;
x = y;
}
if(y != )return false;//费马小定理
}
return true;
}
ll gcd(ll a, ll b)
{
return b == ? a : gcd(b, a % b);
}
ll pollard_rho(ll n, ll c)//找到n的一个因子
{
ll x = rand() % (n - ) + ;
ll y = x, i = , k = ;
while()
{
i++;
x = (mul(x, x, n) + c) + n;//不断调整x2
ll d = gcd(y - x, n);
if( < d && d < n)
return d;//找到因子
if(y == x)
return n;//找到循环,返回n,重新来
if(i == k)//一个优化
{
y = x;
k <<= ;
}
}
}
void Find(ll n, ll c)
{
if(n == )return;//递归出口 if(Miller_Rabin(n, times))//如果是素数,就加入
{
m[n]++;
return;
} ll p = n;
while(p >= n)
p = pollard_rho(p, c--);//不断找因子,知道找到为止,返回n说明没找到 Find(p, c);
Find(n / p, c);
}
ll pow2(ll a, ll b)
{
ll ans = ;
while(b)
{
if(b & )ans *= a;
b /= ;
a *= a;
}
return ans;
}
int main()
{
ll x, y;
ll a[], b[];
//srand((unsigned)time(NULL));
while(cin >> x >> y)
{
m.clear();
y = y / x;
Find(y, );//这是自己设置的一个数
map<ll, int>::iterator it = m.begin();
for(int i = ; it != m.end(); it++, i++)
{
a[i] = it->first;
b[i] = it->second;
}
ll Max = INF, ansa, ansb;
int t = m.size();
for(int i = ; i < (<<t); i++)
{
ll tot = ;
for(int j = ; j < t; j++)
{
if(i & (<<j))
tot *= pow2(a[j], b[j]);
}
ll cnt = tot + y / tot;
if(cnt < Max)
{
Max = cnt;
ansa = tot;
ansb = y / tot;
}
}
if(ansa > ansb)swap(ansa, ansb);
cout<<ansa*x<<" "<<ansb*x<<endl;
}
return ;
}
POJ-2429 GCD & LCM Inverse---给出gcd和lcm求原来两个数的更多相关文章
- 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数 例如给定nums = [2,7,11,15],target = 9
python解决方案 nums = [1,2,3,4,5,6] #假如这是给定的数组 target = 9 #假如这是给定的目标值 num_list = [] #用来装结果的容器 def run(nu ...
- [POJ 2429] GCD & LCM Inverse
GCD & LCM Inverse Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10621 Accepted: ...
- poj 2429 GCD & LCM Inverse 【java】+【数学】
GCD & LCM Inverse Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9928 Accepted: ...
- Mathematics:GCD & LCM Inverse(POJ 2429)
根据最大公约数和最小公倍数求原来的两个数 题目大意,不翻译了,就是上面链接的意思. 具体思路就是要根据数论来,设a和b的GCD(最大公约数)和LCM(最小公倍数),则a/GCD*b/GCD=LCM/G ...
- 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 ...
- POJ2429 GCD & LCM Inverse pollard_rho大整数分解
Given two positive integers a and b, we can easily calculate the greatest common divisor (GCD) and t ...
- 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 这 ...
- POJ:2429-GCD & LCM Inverse(素数判断神题)(Millar-Rabin素性判断和Pollard-rho因子分解)
原题链接:http://poj.org/problem?id=2429 GCD & LCM Inverse Time Limit: 2000MS Memory Limit: 65536K To ...
- POJ2429_GCD & LCM Inverse【Miller Rabin素数測试】【Pollar Rho整数分解】
GCD & LCM Inverse Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9756Accepted: 1819 ...
随机推荐
- php的stristr()函数,查找字符
1.用法,要传2个参数 stristr(string,search):查找并返还匹配后,剩下的部分字符串 查找过程不区分大小写,要区分大小写用 strstr(string,search)少一个字母i ...
- Linux中常用头文件的作用--转
http://blog.sina.com.cn/s/blog_5c93b2ab0100q62k.html 1. Linux中一些头文件的作用: <assert.h>:ANSI C.提供断言 ...
- golang获取变量数据类型
如果某个函数的入参是interface{},有下面几种方式可以获取入参的方法: 1 fmt: import "fmt" func main() { v := "hello ...
- SSH,SSM框架文件上传
一.了解文件上传 1.1 什么是文件上传 将本地文件通过流的形式写到服务器上 1.2 文件上传的技术 JspSmartUpload: 其组件是应用jsp进行B/S程序开发过 ...
- java编写简单的语法分析预测程序
编译原理课程中,编了一个简单的语法分析预测程序,这个程序时根据固定的文法得到预测分析表,然后编写程序来判断表达式是否会正确推到出来. 前提是程序没有左递归符合LL(1)文法: 文法如下: E→TE' ...
- Collections自定义List排序规则
Collections自定义List排序规则 //这里的顺序,是我自己定义的一个List<String> String[] regulation = {"jams",& ...
- SpringBoot加载子模块配置文件的方法
这两天开始学习SpringBoot框架,按照官方的文档,很轻易地就把单模块的项目启动了,但在使用maven搭建多模块的时候遇到了子模块配置文件没有加载的问题 项目架构是这样的 zero |-ws |- ...
- 在JSP中将EXEL文件的数据传入到数据库中
在jsp中: 在script中使用函数: $(function(){ //var lpyear = document.getElementById("lpyear").value; ...
- 封装hiredis——C++与redis对接(一)(string的SET与GET操作)
在菜鸟教程自学了redis,总想着像Mysql一样,在C/C++中进行对接.于是查询了一些资料,最后找到了hiredis.然而直接用它的话,难免有点不方便.于是,对其进行封装. hiredis直接去g ...
- Java CAS总结
文章目录 1. CPU指令对CAS的支持(CPU的cas指令是原子的) 或许我们可能会有这样的疑问,假设存在多个线程执行CAS操作并且CAS的步骤很多,有没有可能在判断V和E相同后,正要赋值时,切换了 ...